package cn.com.generaldata.os.service.impl.web;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Pattern;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.nutz.castor.Castors;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.entity.Entity;
import org.nutz.dao.entity.Record;
import org.nutz.dao.impl.sql.SqlTemplate;
import org.nutz.dao.sql.Criteria;
import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.json.Json;
import org.nutz.lang.Mirror;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import cn.com.generaldata.jsme_indicator_system.entity.DustryReportNz;
import cn.com.generaldata.jsme_indicator_system.entity.Indicator;
import cn.com.generaldata.jsme_indicator_system.entity.IndicatorRelation;
import cn.com.generaldata.jsme_indicator_system.entity.ReportDetailNz;
import cn.com.generaldata.jsme_indicator_system.entity.ReportNz;
import cn.com.generaldata.jsme_indicator_system.entity.ReportTypeIndicator;
import cn.com.generaldata.jsme_indicator_system.entity.ReportTypeLimit;
import cn.com.generaldata.jsme_indicator_system.entity.ReportTypeNz;
import cn.com.generaldata.jsme_indicator_system.entity.ReportTypeUnit;
import cn.com.generaldata.jsme_indicator_system.entity.ReportTypeUnitType;
import cn.com.generaldata.jsme_indicator_system.entity.StatSystem;
import cn.com.generaldata.jsme_indicator_system.entity.UnitNz;
import cn.com.generaldata.jsme_indicator_system.util.Constants;
import cn.com.generaldata.jsme_indicator_system.vo.reportdesigner.ReportExcelSectionVO;
import cn.com.generaldata.jsme_indicator_system.vo.reportdesigner.ReportExcelSectionVO.ReportExcelInputInfo;
import cn.com.generaldata.os.common.Excels;
import cn.com.generaldata.os.constant.FilterConstant;
import cn.com.generaldata.os.constant.ReportConstant;
import cn.com.generaldata.os.dao.impl.ReportDAO;
import cn.com.generaldata.os.dao.intf.BaseDAOInterface;
import cn.com.generaldata.os.newpojo.ReportType;
import cn.com.generaldata.os.newpojo.ReportVersion;
import cn.com.generaldata.os.paging.Event;
import cn.com.generaldata.os.paging.Filter;
import cn.com.generaldata.os.paging.FilterRule;
import cn.com.generaldata.os.paging.Page;
import cn.com.generaldata.os.paging.Result;
import cn.com.generaldata.os.pojo.Area;
import cn.com.generaldata.os.pojo.AreaPerform;
import cn.com.generaldata.os.pojo.BillboardIndustry;
import cn.com.generaldata.os.pojo.BillboardIndustryReports;
import cn.com.generaldata.os.pojo.DustryReport;
import cn.com.generaldata.os.pojo.Industry;
import cn.com.generaldata.os.pojo.Report;
import cn.com.generaldata.os.pojo.ReportAttach;
import cn.com.generaldata.os.pojo.ReportDetail;
import cn.com.generaldata.os.pojo.ReportHistory;
import cn.com.generaldata.os.pojo.ReportMarking;
import cn.com.generaldata.os.pojo.ReportUnit;
import cn.com.generaldata.os.pojo.Role;
import cn.com.generaldata.os.pojo.Unit;
import cn.com.generaldata.os.pojo.User;
import cn.com.generaldata.os.pojo.UserIndustry;
import cn.com.generaldata.os.pojo.mvc.Row;
import cn.com.generaldata.os.service.common.HistoryService;
import cn.com.generaldata.os.service.common.MarkingService;
import cn.com.generaldata.os.service.common.ReportExcelTemplateBuilder;
import cn.com.generaldata.os.service.common.UserService;
import cn.com.generaldata.os.service.impl.SendReportService;
import cn.com.generaldata.os.util.BeanMapper;
import cn.com.generaldata.os.vo.ReportVO;
import cn.com.generaldata.os.zip.ZipCompressor;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

@Component
public class ReportServiceForWeb {
	private static Logger log = LoggerFactory.getLogger(ReportServiceForWeb.class);

	@Autowired
	private ReportDAO reportDAOIpml;

	@Autowired
	@Qualifier("baseDAO")
	private BaseDAOInterface<Report> reportDAO;

	@Autowired
	@Qualifier("baseDAO")
	private BaseDAOInterface<ReportDetail> reportDetailDAO;

	private final AtomicInteger dirCount = new AtomicInteger(1);

	@Autowired
	@Qualifier("baseDAO")
	private BaseDAOInterface<Industry> industryDAO;

	@Autowired
	@Qualifier("baseDAO")
	private BaseDAOInterface<Unit> unitDAO;

	@Autowired
	private ReportExcelTemplateBuilder reportExcelTemplateBuilder;

	@Autowired
	@Qualifier("sqlTemplate")
	private SqlTemplate sqlTemplate;

	@Autowired
	@Qualifier("indicatorSystemSqlTemplate")
	private SqlTemplate indicatorSystemSqlTemplate;

	@Autowired
	@Qualifier("baseDAO")
	private BaseDAOInterface<BillboardIndustry> billboardIndustryDAO;

	@Autowired
	@Qualifier("baseDAO")
	private BaseDAOInterface<BillboardIndustryReports> billboardIndustryReportsDAO;

	@Autowired
	@Qualifier("baseDAO")
	private BaseDAOInterface<UserIndustry> userIndustryDAO;

	@Autowired
	@Qualifier("baseDAO")
	private BaseDAOInterface<ReportType> reportTypeDAO;

	@Autowired
	@Qualifier("baseDAO")
	private BaseDAOInterface<DustryReport> dustryReportDAO;

	@Autowired
	@Qualifier("baseDAO")
	private BaseDAOInterface<ReportMarking> reportMarkingDAO;

	@Autowired
	@Qualifier("baseDAO")
	private BaseDAOInterface<ReportHistory> reportHistoryDAO;

	@Autowired
	@Qualifier("baseDAO")
	private BaseDAOInterface<ReportUnit> reportUnitDAO;

	@Autowired
	@Qualifier("baseDAO")
	private BaseDAOInterface<User> userDAO;

	@Autowired
	@Qualifier("baseDAO")
	private BaseDAOInterface<ReportAttach> reportAttachDAO;

	@Autowired
	@Qualifier("unitServiceForWeb")
	private UnitServiceForWeb unitService;

	@Autowired
	@Qualifier("indicatorSystemDao")
	private Dao indicatorSystemDao;

	@Autowired
	@Qualifier("baseDAO")
	private BaseDAOInterface<ReportVersion> versionDAO;

	@Autowired
	@Qualifier("baseDAO")
	private BaseDAOInterface<AreaPerform> areaPerformDAO;

	@Autowired
	@Qualifier("baseDAO")
	private BaseDAOInterface<Area> areaDAO;

	@Autowired
	private MarkingService markingService;

	@Autowired
	private HistoryService historyService;
	private final SimpleDateFormat sfd = new SimpleDateFormat("yyyy/MM");
	private final DecimalFormat df = new DecimalFormat("#.##");
	//	private final String[] areas = new String[] { "320600000000000", "320900000000000", "320700000000000" };

	// 自加
	@Autowired
	private UserService userService;

	private static String regx = "^((-?\\d+.?\\d*)[Ee]{1}(-?\\d+))$";// 科学计数法正则表达式
	private static Pattern pattern = Pattern.compile(regx);
	/** 指标取值方式 - 取值 */
	private static final int GET_VALUE_TYPE_GET = 1;
	/** 指标取值方式 - 汇总 **/
	private static final int GET_VALUE_TYPE_SUM = 2;

	private final Mirror<ReportDetail> reportDetailMirror = Mirror.me(ReportDetail.class);
	private final Mirror<ReportDetailNz> reportDetaiNzMirror = Mirror.me(ReportDetailNz.class);
	
	@Autowired
	private SendReportService sendReportService;

	// private AutoPushingServiceInterface apServiceInterface;
	// public void setApServiceInterface(AutoPushingServiceInterface
	// apServiceInterface) {
	// this.apServiceInterface = apServiceInterface;
	// }

	public List<ReportTypeLimit> queryReportLimit(Integer statSystem, String reportTypeId, String typeTime,
			String typeYear) {
		String sql = "select * from REPORT_TYPE_LIMIT where 1=1";
		HashMap map = new HashMap();
		if (statSystem != null) {
			sql += " and STAT_SYSTEM=@statSystem";
			map.put("statSystem", statSystem);
		}
		List<ReportTypeLimit> query = sqlTemplate.query(sql, map, indicatorSystemDao.getEntity(ReportTypeLimit.class));
		return query;
	}

	/**
	 * 将可以获取上期数据的指标值设置到汇总表中
	 * 
	 * @param reportType
	 * @param lastTimeIndicatorMap
	 * @param accounting
	 */

	public void addLasttimeCellReportToAccount(ReportType reportType, Map lastTimeIndicatorMap, Map accounting) {
		String sql = "SELECT  t.id  FROM  T_INDICATOR T "
				+ "INNER JOIN T_REPORT_TYPE_INDICATOR rti ON T.ID = RTI.INDICATOR_ID "
				+ "AND RTI.REPORT_TYPE_ID = @reportTypeId  WHERE  T.GET_LAST_TIME_DATA = 1 ";
		Map<String, Object> params = ImmutableMap.<String, Object> of("reportTypeId", reportType.getId());
		List<Integer> indicatorIds = sqlTemplate.queryForList(sql, null, params, Integer.class);
		for (Integer indicatorId : indicatorIds) {
			String indicatorVal = (String) lastTimeIndicatorMap.get(indicatorId);
			if (StringUtils.isBlank(indicatorVal)) {
				continue;
			}
			Map<String, String> map = (Map<String, String>) accounting.get(indicatorId);
			if (map == null) {
				map = ImmutableMap.of("上期数据", indicatorVal);
				accounting.put(indicatorId, map);
			} else {
				map.put(indicatorId.toString(), indicatorVal);
			}
		}
	}

	/**
	 * 获取上期数据行式报表数据
	 * 
	 * @param user
	 * @param reportType
	 * @param timeDate
	 * @param quarterDate
	 * @return
	 */

	public List<Row> getLasttimeRowReportRow(User user, ReportType reportType, String timeDate, String quarterDate) {
		Report lasttimeReport = getReportByParam(user, reportType, timeDate, quarterDate);
		List<Row> rows = Lists.newArrayList();
		if (lasttimeReport == null) {
			return rows;
		}
		Filter reportFilter = new Filter();
		reportFilter.addRule(new FilterRule(FilterConstant.EQUAL, "report.id", lasttimeReport.getId()));
		reportFilter.setOrder(FilterConstant.ASC);
		reportFilter.setSortBy("rowIndex");
		List<ReportDetail> list = reportDetailDAO.find(ReportDetail.class, reportFilter, null);

		List<ReportDetail> rds = null;
		// 不跨版本
		if (reportType.getId().equals(lasttimeReport.getReportTypeId())) {
			List<Indicator> indicators = getIndicatorsByReportTypeId(lasttimeReport.getReportTypeId());
			List<ReportDetail> newRds = Lists.newArrayList();
			for (int i = 0; i < list.size(); i++) {
				ReportDetail newRd = new ReportDetail();
				newRds.add(newRd);
			}
			for (Indicator indicator : indicators) {
				if (indicator.getGetLastTimeData() == Constants.NO) {
					Cnd indicatorRelCnd = Cnd.where("indicatorId", "=", indicator.getId()).and("reportTypeId", "=",
							lasttimeReport.getReportTypeId());
					ReportTypeIndicator indicatorRel = indicatorSystemDao.fetch(ReportTypeIndicator.class,
							indicatorRelCnd);
					String fieldName = String.format("f%d", indicatorRel.getTheColumn());
					for (int i = 0, length = list.size(); i < length; i++) {
						ReportDetail oldRd = list.get(i);
						ReportDetail newRd = newRds.get(i);

						String oldFieldVal = (String) reportDetailMirror.getValue(oldRd, fieldName);
						reportDetailMirror.setValue(newRd, fieldName, oldFieldVal);

					}
				}
			}
			rds = newRds;
		} else {
			String lasttimeReportTypeId = lasttimeReport.getReportTypeId();

			List<ReportDetail> newRds = Lists.newArrayList();
			for (int i = 0; i < list.size(); i++) {
				ReportDetail newRd = new ReportDetail();
				newRds.add(newRd);
			}

			List<ReportTypeIndicator> newRels = indicatorSystemDao.query(ReportTypeIndicator.class,
					Cnd.where("reportTypeId", "=", reportType.getId()));
			for (ReportTypeIndicator newRti : newRels) {
				Indicator indicator = indicatorSystemDao.fetch(Indicator.class, newRti.getIndicatorId());
				if (indicator.getGetLastTimeData() == Constants.YES) {
					Cnd oldRtiCnd = Cnd.where("reportTypeId", "=", lasttimeReportTypeId).and("indicatorId", "=",
							indicator.getId());
					ReportTypeIndicator oldRti = indicatorSystemDao.fetch(ReportTypeIndicator.class, oldRtiCnd);

					String oldFieldName = String.format("f%d", oldRti.getTheColumn());
					String newFieldName = String.format("f%d", newRti.getTheColumn());
					for (int i = 0, length = list.size(); i < length; i++) {
						ReportDetail oldRd = list.get(i);
						ReportDetail newRd = newRds.get(i);

						String oldFieldVal = (String) reportDetailMirror.getValue(oldRd, oldFieldName);
						reportDetailMirror.setValue(newRd, newFieldName, oldFieldVal);

					}
				}
			}

			rds = newRds;
		}

		for (ReportDetail rd : rds) {
			Row row = new Row();
			row = BeanMapper.map(rd, Row.class);
			row.setRowId("");
			row.setRowType(Row.ROW_TYPE_ACCOUNT);
			rows.add(row);
		}
		return rows;
	}

	/**
	 * 
	 * @param reportTypeId
	 * @return
	 */
	private List<Indicator> getIndicatorsByReportTypeId(String reportTypeId) {
		String sql = "SELECT  T.*  FROM  T_INDICATOR T "
				+ "INNER JOIN T_REPORT_TYPE_INDICATOR rti ON T.ID = RTI.INDICATOR_ID "
				+ "AND RTI.REPORT_TYPE_ID = @reportTypeId ";
		Map<String, Object> params = ImmutableMap.<String, Object> of("reportTypeId", reportTypeId);
		return sqlTemplate.query(sql, params, indicatorSystemDao.getEntity(Indicator.class));
	}

	/**
	 * 汇总本级涉海部门和下级单位的报表信息ID
	 */

	public List<String> generelReportsDetail(String unitId, ReportType rType, String timeDate, String quarterDate) {
		String yearValue = timeDate.substring(0, 4);
		int year = Integer.valueOf(yearValue);
		String nextYearValue = String.valueOf(year + 1);
		String monthVlaue = timeDate.substring(5, 7);
		// 获取下一年年份月份（因为套用的查询上期报表信息方法，那个方法传的是上年的年份，所以这里把年份+1，就相当于当年年份了）
		String nextTimeDate = nextYearValue + "/" + monthVlaue;
		String hql = "from Unit as u where 1=1";
		HashMap map = new HashMap();
		// 获取下级单位和本级涉海部门列表
		if (StringUtils.isNotBlank(unitId)) {
			hql += " and exists (select a.id from UnitRelation as a where a.cid=u.id and a.pid=:unitId) and (u.role.id=4 or u.role.id=5)";
			map.put("unitId", unitId);
		}
		Result hqlParam = unitDAO.hqlParam(hql, map, null);
		List<Unit> list = (List<Unit>) hqlParam.getOperationResult();
		List<String> reportIds = new ArrayList<String>();
		hql = "from User as us where exists (select u.id from Unit as u where u.id=us.userUnit.id and u.id=:unitId)";
		for (Unit unit : list) {
			map.put("unitId", unit.getId());
			Result userResult = userDAO.hqlParam(hql, map, null);
			List<User> userlist = (List<User>) userResult.getOperationResult();
			User user = userlist.get(0);
			Report reportByParam = getReportByParam(user, rType, nextTimeDate, quarterDate);
			if (reportByParam != null) {
				reportIds.add(reportByParam.getId());
			}
		}
		return reportIds;
	}

	public Report getReportByParam(User user, ReportType reportType, String timeDate, String quarterDate) {
		String yearValue = "";
		String upYearValue = "";
		String reportYearTime = "";
		String monthVlaue = "";
		Integer quarterValue = 0;
		Filter filter = new Filter();
		// 频率
		String timeType = reportType.getTypeTime();
		// 年报类别
		String yearType = reportType.getTypeYearTime();
		Filter userfilter = new Filter();
		userfilter.addRule(new FilterRule(FilterConstant.EQUAL, "role.id", ReportConstant.OCEAN));
		userfilter.addRule(new FilterRule(FilterConstant.EQUAL, "area.id", ReportConstant.PROVINCE_AREA_ID));
		List<User> oper = userDAO.find(User.class, userfilter, null);
		String[] opids = new String[oper.size()];
		for (int i = 0; i < oper.size(); i++) {
			opids[i] = oper.get(i).getId();
		}
		if (!(oper.size() > 0)) {
			opids = new String[] { "" };
		}
		Filter filterU = new Filter();
		filterU.addRule(new FilterRule(FilterConstant.EQUAL, "userUnit.id", user.getUserUnit().getId()));
		// 该单位的所有用户
		List<User> users = userDAO.find(User.class, filterU, null);
		String[] uids = new String[users.size()];
		for (int i = 0; i < users.size(); i++) {
			uids[i] = users.get(i).getId();
		}
		if (!(users.size() > 0)) {
			uids = new String[] { "" };
		}
		// List<String> uids=new ArrayList<String>();
		// for(User u:users)
		// uids.add(u.getId());
		// Integer preVersion = reportType.getPreVersionId();
		List<String> reportTypeIds = new ArrayList<String>();
		reportTypeIds.add(reportType.getId());
		if (StringUtils.isNotBlank(reportType.getPrevVersionId())) {
			reportTypeIds.add(reportType.getPrevVersionId());
		}
		// Calendar date = Calendar.getInstance();
		yearValue = timeDate.substring(0, 4);
		int year = Integer.valueOf(yearValue);
		upYearValue = String.valueOf(year - 1);
		monthVlaue = timeDate.substring(5, 7);
		int month = Integer.valueOf(monthVlaue);
		Calendar dateNow = Calendar.getInstance();
		dateNow.set(dateNow.YEAR, year);
		//上个月
		dateNow.set(dateNow.MONTH, month - 2);
		//上一季度
		String lasttimeQuarterDate = "第零季度";
		if ("第一季度".equals(quarterDate))
			quarterValue = 4;
		else if ("第二季度".equals(quarterDate))
			quarterValue = 1;
		else if ("第三季度".equals(quarterDate))
			quarterValue = 2;
		else if ("第四季度".equals(quarterDate))
			quarterValue = 3;
		List<Report> reports = new ArrayList<Report>();
		if (timeType.equals("0")) { // 月报
			filter.addRule(new FilterRule(FilterConstant.COLLECTION, "user.id", uids));
			filter.addRule(new FilterRule(FilterConstant.EQUAL, "month",
					Integer.valueOf(dateNow.get(dateNow.MONTH) + 1)));
			filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportYear", String.valueOf(dateNow.get(dateNow.YEAR))));
			filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportTimetype", timeType));
			filter.addRule(new FilterRule(FilterConstant.COLLECTION, "reportTypeId", reportTypeIds.toArray()));
			reports = reportDAO.find(Report.class, filter, null);
		} else if (timeType.equals("1")) { // 年报
			// 当前时间
			Calendar date = Calendar.getInstance();
			int monthValue = date.get(Calendar.MONTH);
			// 全年报时，获取去年的上报记录
			if (yearType.equals("2")) {
				reportYearTime = "2";
				filter.addRule(new FilterRule(FilterConstant.COLLECTION, "user.id", uids));
				filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportYear", upYearValue));
				filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportYearTime", reportYearTime));
				filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportTimetype", timeType));
				filter.addRule(new FilterRule(FilterConstant.COLLECTION, "reportTypeId", reportTypeIds.toArray()));
				reports = reportDAO.find(Report.class, filter, null);
			} else if (yearType.equals("1")) { // 半年报
				// 查上年全年
				if (monthValue < 6) {
					reportYearTime = "2";
					upYearValue = String.valueOf(Integer.valueOf(upYearValue) - 1);
				}
				// 查今年半年
				else {
					// 首先获取当前年的第一次上报记录
					reportYearTime = "1";
				}
				filter.addRule(new FilterRule(FilterConstant.COLLECTION, "user.id", uids));
				filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportYear", upYearValue));
				filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportYearTime", reportYearTime));
				filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportTimetype", timeType));
				filter.addRule(new FilterRule(FilterConstant.COLLECTION, "reportTypeId", reportTypeIds.toArray()));
				reports = reportDAO.find(Report.class, filter, null);
			}
		}
		if (timeType.equals("2")) { // 季报
			filter.addRule(new FilterRule(FilterConstant.COLLECTION, "user.id", uids));
			if (quarterValue.intValue() == 4)
				filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportYear", upYearValue));
			else
				filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportYear", yearValue));
			filter.addRule(new FilterRule(FilterConstant.EQUAL, "quarter", quarterValue));
			filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportTimetype", timeType));
			filter.addRule(new FilterRule(FilterConstant.COLLECTION, "reportTypeId", reportTypeIds.toArray()));
			reports = reportDAO.find(Report.class, filter, null);
		}
		if (reports.size() > 0) {
			return reports.get(0);
		}
		return null;
	}

	public List<String> queryTypeNo(Integer type) {
		String sql = "select new ReportType(typeNo) from ReportType where statSystem=" + type
				+ " order by sortNo,subSortNo";

		List<ReportType> unitList = reportTypeDAO.findByHql(sql, null);
		List<String> typeNoList = new ArrayList<String>();
		for (ReportType rt : unitList) {
			typeNoList.add(rt.getTypeNo());
		}
		return new ArrayList<String>(new LinkedHashSet<String>(typeNoList));
	}

	public int queryReportsByBillboardTime(String typeCode, String timeType, String yearType, String quarterDate,
			String billboardTime, String reportVersion, String units) {
		String vSystem;
		String yearValue;
		String reportYearTime = null;
		String monthValue;
		String upYearValue;
		String upMonthValue;
		List<Report> reports = new ArrayList<Report>();
		if (billboardTime == null || "".equals(billboardTime)) {
			billboardTime = sfd.format(new Date());
		}
		List<String> userList = new ArrayList<String>();
		if (!StringUtils.isBlank(units)) {
			String[] split = units.split(",");
			for (String unitId : split) {
				Filter filterUser = new Filter();
				filterUser.addRule(new FilterRule(FilterConstant.EQUAL, "userUnit.id", unitId));
				List<User> find = userDAO.find(User.class, filterUser, null);
				if (find != null && find.size() > 0)
					userList.add(find.get(0).getId());
			}
		}
		// 鑾峰彇鎶ヨ〃鍒跺害瀵瑰簲鐨勭増鏈�
		// vSystem = reportVersion.substring(reportVersion.indexOf("(") + 1,
		// reportVersion.indexOf(")"));
		// Filter filter1 = new Filter();
		// filter1.setOrder(FilterConstant.DESC);
		// filter1.setSortBy("versionNumber");
		// if (StringUtils.isNotBlank(vSystem)) {
		// filter1.addRule(new FilterRule(FilterConstant.EQUAL, "versionName",
		// vSystem));
		// }
		// ReportVersion version = this.getVersion(filter1, null);
		String monthVlaue = billboardTime;
		Filter filter = new Filter();
		// 月报
		if (timeType.equals("0")) {
			filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportMonth", billboardTime));
			filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportTimetype", timeType));
			filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportTypeId", typeCode));
			filter.addRule(new FilterRule(FilterConstant.NOT_EQUAL, "reportCheckStatus", Short.valueOf("0")));
			// filter.addRule(new FilterRule(FilterConstant.EQUAL,
			// "reportVersion", version.getVersionNumber()));
			reports = reportDAO.find(Report.class, filter, null);
		}
		// 年报
		if (timeType.equals("1")) {
			yearValue = billboardTime.substring(0, 4);
			monthValue = billboardTime.substring(5);
			if (yearType.equals("1") || yearType.equals("4")) { // 半年报（实际没有4）
				// 2013/04
				if (Integer.valueOf(monthValue) > 6) {
					reportYearTime = "1"; // (上半年报)
					filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportYear", yearValue));
					filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportYearTime", reportYearTime));
					filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportTimetype", timeType));
				} else if (Integer.valueOf(monthValue) < 7) {
					// （去年全年报）
					filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportYear", String.valueOf(Integer
							.valueOf(yearValue) - 1)));
					filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportTimetype", "2"));
				}

				filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportTypeId", typeCode));
				filter.addRule(new FilterRule(FilterConstant.NOT_EQUAL, "reportCheckStatus", Short.valueOf("0")));
				// filter.addRule(new FilterRule(FilterConstant.EQUAL,
				// "reportVersion", version.getVersionNumber()));
				reports = reportDAO.find(Report.class, filter, null);
			} else if (yearType.equals("2")) { // 全年报
				reportYearTime = "2";
				filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportYear", yearValue));
				filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportYearTime", reportYearTime));
				filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportTimetype", timeType));
				filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportTypeId", typeCode));
				filter.addRule(new FilterRule(FilterConstant.NOT_EQUAL, "reportCheckStatus", Short.valueOf("0")));
				// filter.addRule(new FilterRule(FilterConstant.EQUAL,
				// "reportVersion", version.getVersionNumber()));
				reports = reportDAO.find(Report.class, filter, null);
			}
		}
		// 季报
		if (timeType.equals("2")) {
			yearValue = billboardTime;
			if (quarterDate == null || !"".equals(quarterDate)) {
				Date parse = new Date();
				try {
					parse = sfd.parse(billboardTime);
				} catch (ParseException e) {
					// TODO Auto-generated catch block
					log.error("日期转换错误", e);
				}
				int month = parse.getMonth();
				if (month >= 0 && month < 3) {
					quarterDate = "第一季度";
				}
				if (month >= 3 && month < 6) {
					quarterDate = "第二季度";
				}
				if (month >= 6 && month < 9) {
					quarterDate = "第三季度";
				}
				if (month >= 9 && month < 12) {
					quarterDate = "第四季度";
				}
			}
			filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportYear", yearValue.substring(0, 4)));
			filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportQuarter", quarterDate));
			// filter.addRule(new FilterRule(FilterConstant.EQUAL,
			// "reportTimetype", timeType));
			filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportTypeId", typeCode));
			filter.addRule(new FilterRule(FilterConstant.NOT_EQUAL, "reportCheckStatus", Short.valueOf("0")));
			// filter.addRule(new FilterRule(FilterConstant.EQUAL,
			// "reportVersion", version.getVersionNumber()));
			reports = reportDAO.find(Report.class, filter, null);
		}
		int sum = 0;
		if (reports.size() > 0) {
			for (Report report : reports) {
				if (userList.contains(report.getUser().getId()))
					sum++;
			}

		}
		return sum;
	}

	public String createMVCReport(cn.com.generaldata.os.pojo.mvc.Report report) {
		if (report == null || report.getRows() == null || report.getRows().size() < 1) {
			// throw new
			// CommonException(ExceptionConstant.MSG_ILLEGAL_PARAMETER);
			log.error("report为空");
			return null;
		}

		if (StringUtils.isBlank(report.getReportOperatorId())) {
			// throw new
			// CommonException(ExceptionConstant.MSG_OPERATOR_IS_NULL);
			log.error("操作人为空");
			return null;
		}

		Date date = new Date();
		Calendar dateCurr = Calendar.getInstance();
		int year = dateCurr.get(Calendar.YEAR);
		int month = dateCurr.get(Calendar.MONTH);
		// 转换Report对象
		Report persistReport = toPersistReport(report);
		// 年报
		if ("1".equals(persistReport.getReportTimetype())) {
			// 半年报
			if ("1".equals(persistReport.getReportYearTime())) {
				// 不是今年
				if (!String.valueOf(year).equals(persistReport.getReportYear())) {
					// 报全年报
					persistReport.setReportYearTime("2");
				}
			}
			// // 全年报
			// else if ("2".equals(persistReport.getReportYearTime())) {
			// // 是去年
			// if (String.valueOf(year - 1).equals(
			// persistReport.getReportYear())) {
			// // 报去年快报
			// if (month < 7) {
			// persistReport.setReportYearTime("3");
			// }
			// }
			// }
		}
		persistReport.setReportCreateTime(date);
		persistReport.setReportLastEditTime(date);
		persistReport.setSelfSet1(report.getSelfSet1());
		persistReport.setSelfSet2(report.getSelfSet2());
		persistReport.setSelfSet3(report.getSelfSet3());
		persistReport.setSelfSet4(report.getSelfSet4());
		persistReport.setSelfSet5(report.getSelfSet5());
		persistReport.setReportFlag("0");
		if (persistReport.getId() == null || "".equals(persistReport.getId()))
			persistReport.setId(UUID.randomUUID().toString().replaceAll("-", ""));
		reportDAO.save(persistReport);

		// 转换ReportDetail对象
		Set<ReportDetail> reportDetails = toPersistReportDetail(report);
		for (ReportDetail reportDetail : reportDetails) {
			reportDetail.setReport(persistReport);
			reportDetail.setCreateTime(date);
			reportDetail.setLastEditTime(date);
			if (reportDetail.getId() == null || "".equals(reportDetail.getId()))
				reportDetail.setId(UUID.randomUUID().toString().replaceAll("-", ""));
			reportDetailDAO.save(reportDetail);
		}
	
		return persistReport.getId();
	}

	// 自加

	public String createMVCReport4Mark(cn.com.generaldata.os.pojo.mvc.Report report) {

		if (report == null || report.getRows() == null || report.getRows().size() < 1) {
			// throw new
			// CommonException(ExceptionConstant.MSG_ILLEGAL_PARAMETER);
			log.error("report为空");
			return null;
		}

		if (StringUtils.isBlank(report.getReportOperatorId())) {
			// throw new
			// CommonException(ExceptionConstant.MSG_OPERATOR_IS_NULL);
			log.error("操作人为空");
			return null;
		}

		Date date = new Date();

		// 转换Report对象
		Report persistReport = toPersistReport(report);
		persistReport.setReportCreateTime(date);
		persistReport.setReportLastEditTime(date);
		if (persistReport.getId() == null || "".equals(persistReport.getId()))
			persistReport.setId(UUID.randomUUID().toString().replaceAll("-", ""));
		reportDAO.save(persistReport);

		// 转换ReportDetail对象
		Set<ReportDetail> reportDetails = toPersistReportDetail(report);
		for (ReportDetail reportDetail : reportDetails) {
			reportDetail.setReport(persistReport);
			reportDetail.setCreateTime(date);
			reportDetail.setLastEditTime(date);
			if (reportDetail.getId() == null || "".equals(reportDetail.getId()))
				reportDetail.setId(UUID.randomUUID().toString().replaceAll("-", ""));
			reportDetailDAO.save(reportDetail);
		}

		return persistReport.getId();
	}

	public cn.com.generaldata.os.pojo.mvc.Report modifyMVCReport(cn.com.generaldata.os.pojo.mvc.Report report) {
		// if (report == null || report.getRows() == null ||
		// report.getRows().size() < 1) {
		// throw new CommonException(ExceptionConstant.MSG_ILLEGAL_PARAMETER);
		// }
		// 直接点击“通过”或“驳回”按钮，不操作Rows，因此不进行判断
		if (report == null) {
			// throw new
			// CommonException(ExceptionConstant.MSG_ILLEGAL_PARAMETER);
			log.error("report为空");
			return null;
		}

		if (StringUtils.isBlank(report.getReportOperatorId())) {
			// throw new
			// CommonException(ExceptionConstant.MSG_OPERATOR_IS_NULL);
			log.error("操作人为空");
			return null;
		}

		Date date = new Date();

		// 转换Report对象
		Report persistReport = toPersistReport(report);
		persistReport.setReportLastEditTime(date);
		// if(persistReport.getReportReferenceId() == "" ||
		// persistReport.getReportReferenceId() == null ||
		// persistReport.getReportReferenceId().equals("") ||
		// persistReport.getReportReferenceId().equals(null))
		// persistReport.setReportReferenceId("");

		if ((persistReport.getReportCheckStatus() == ReportConstant.FLAG_PASSED)
				|| (persistReport.getReportCheckStatus() == ReportConstant.FLAG_PROVINCE_PASSED_UNCOMMITTED)) {
			persistReport.setReportCheckSuccessDate(date);
		}
		persistReport.setSelfSet1(report.getSelfSet1());
		persistReport.setSelfSet2(report.getSelfSet2());
		persistReport.setSelfSet3(report.getSelfSet3());
		persistReport.setSelfSet4(report.getSelfSet4());
		persistReport.setSelfSet5(report.getSelfSet5());
		persistReport.setReportFlag("0");
		reportDAO.update(persistReport);
		if (report.getRows().size() > 0) {
			Filter filter = new Filter();
			filter.addRule(new FilterRule(FilterConstant.EQUAL, "report.id", persistReport.getId()));
			List<ReportDetail> find = reportDetailDAO.find(ReportDetail.class, filter, null);
			reportDetailDAO.delete(find);
			// 转换ReportDetail对象
			Set<ReportDetail> reportDetails = toPersistReportDetail(report);
			for (ReportDetail reportDetail : reportDetails) {
				// if (StringUtils.isBlank(reportDetail.getId())) {
				// reportDetail.setCreateTime(date);
				// reportDetail.setLastEditTime(date);
				if (reportDetail.getId() == null || "".equals(reportDetail.getId()))
					reportDetail.setId(UUID.randomUUID().toString().replaceAll("-", ""));
				reportDetailDAO.save(reportDetail);
				// } else {
				// reportDetail.setLastEditTime(date);
				// reportDetailDAO.update(reportDetail);
				// }
			}
		}

		return report;
	}

	public cn.com.generaldata.os.pojo.mvc.Report queryMVCReportById(String id) {
		if (id != null) {
			Report report = reportDAO.get(Report.class, id);

			Filter filter = new Filter();
			filter.setOrder(FilterConstant.ASC);
			filter.setSortBy("rowIndex");
			filter.addRule(new FilterRule(FilterConstant.EQUAL, "report.id", id));

			List<ReportDetail> reportDetails = reportDetailDAO.find(ReportDetail.class, filter, null);

			return toMVCReport(report, reportDetails);
		}
		return null;
	}

	public String createReport(Report report) {
		if (report != null) {
			Date date = new Date();
			report.setReportCreateTime(date);
			report.setReportLastEditTime(date);
			if (report.getId() == null || "".equals(report.getId()))
				report.setId(UUID.randomUUID().toString().replaceAll("-", ""));
			reportDAO.save(report);
			return report.getId();
		}
		return null;
	}

	public Report modifyReport(Report report) {
		if (report != null) {
			report.setReportLastEditTime(new Date());
			report.setReportFlag("0");
			reportDAO.update(report);
			return report;
		}
		return null;
	}

	public Report queryReportById(String id) {
		if (id != null) {
			return reportDAO.get(Report.class, id);
		}
		return null;
	}

	public cn.com.generaldata.os.pojo.mvc.Report queryReport2AutoValidate(String reportUnit, String reportTypeCode,
			String reportYear, String reportQuarter) {
		Filter filter = new Filter();
		filter.setOrder(FilterConstant.DESC);
		filter.setSortBy("reportDate");

		if (StringUtils.isNotBlank(reportUnit)) {
			filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportUnit", reportUnit));
		}

		if (StringUtils.isNotBlank(reportTypeCode)) {
			filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportTypeId", reportTypeCode));
		}

		if (StringUtils.isNotBlank(reportYear)) {
			filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportYear", reportYear));
		}

		if (StringUtils.isNotBlank(reportQuarter)) {
			filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportQuarter", reportQuarter));
		}

		List<Report> reports = reportDAO.find(Report.class, filter, null);
		if (reports.size() > 0) {
			Report report = reports.get(0);

			Filter detailFilter = new Filter();
			detailFilter.setOrder(FilterConstant.ASC);
			detailFilter.setSortBy("rowIndex");
			detailFilter.addRule(new FilterRule(FilterConstant.EQUAL, "report.id", report.getId()));
			List<ReportDetail> reportDetails = reportDetailDAO.find(ReportDetail.class, detailFilter, null);

			return toMVCReport(report, reportDetails);
		}

		return null;
	}

	// 改变附件状态

	public void modiReportAttachsDisposal(String[] ids) {
		ReportAttach reportAttach = new ReportAttach();
		if (ids != null && ids.length > 0) {
			for (String id : ids) {
				Filter filter = new Filter();
				filter.addRule(new FilterRule(FilterConstant.EQUAL, "attachId", id));
				List<ReportAttach> reportAttachs = reportAttachDAO.find(ReportAttach.class, filter, null);
				if (reportAttachs.size() > 0) {
					reportAttach = reportAttachs.get(0);
					reportAttach.setIsDisposal(1);
					reportAttachDAO.update(reportAttach);
				}
				filter.getRules().clear();
			}
		}
	}

	// 改变附件状态

	public void modiAttachDisposal(String attachId, String attachDisposal) {
		ReportAttach reportAttach = new ReportAttach();
		Filter filter = new Filter();
		filter.addRule(new FilterRule(FilterConstant.EQUAL, "attachId", attachId));
		List<ReportAttach> reportAttachs = reportAttachDAO.find(ReportAttach.class, filter, null);
		if (reportAttachs.size() > 0) {
			reportAttach = reportAttachs.get(0);
			reportAttach.setAttachExplain(attachDisposal);
			reportAttachDAO.update(reportAttach);
		}
		filter.getRules().clear();
	}

	public Result queryReports(Filter filter, Page page) {
		if (filter == null) {
			filter = new Filter();
		}
		if (StringUtils.isBlank(filter.getSortBy())) {
			filter.setSortBy("reportDate");
			filter.setOrder(FilterConstant.DESC);
		}

		List<Report> reports = reportDAO.find(Report.class, filter, page);
		int count = reportDAO.count(Report.class, filter);

		if (page == null) {
			return new Result(1, 1, count, reports, new ArrayList<Event>());
		}
		return new Result(page.getPageNumber(), page.getPageSize(), count, reports, new ArrayList<Event>());
	}

	public Result queryReportsByQBC(DetachedCriteria dc, Page page) {
		// if (filter == null) {
		// filter = new Filter();
		// }
		// if (StringUtils.isBlank(filter.getSortBy())) {
		// filter.setSortBy("reportDate");
		// filter.setOrder(FilterConstant.DESC);
		// }
		List list = reportDAO.findByCriteria(dc);
		List<Report> reports = new ArrayList<Report>();
		if (page == null) {
			reports = reportDAO.findByCriteriaPage(dc.addOrder(Order.desc("reportDate")), 1, 20);
			return new Result(1, 1, list.size(), reports, new ArrayList<Event>());
		} else {
			reports = reportDAO.findByCriteriaPage(dc.addOrder(Order.desc("reportDate")), page.getFirstResult(),
					page.getPageSize());
			// List<Forum> list = r
			// List<Forum> list =
			// this.find(sql.append(where+"order by t.createDate desc").toString(),
			// startIndex,
			// pageSize);
			// dc2.setProjection(Projections.rowCount());
			// List findByCriteria = this.findByCriteria(dc2);
			// int count = reportDAO.count(Report.class, filter);
		}

		return new Result(page.getPageNumber(), page.getPageSize(), list.size(), reports, new ArrayList<Event>());
	}

	public void removeReports(String[] ids) {
		if (ids != null && ids.length > 0) {
			Filter filter = new Filter();
			filter.addRule(new FilterRule(FilterConstant.COLLECTION, "report.id", ids));
			List<ReportDetail> reportDetails = reportDetailDAO.find(ReportDetail.class, filter, null);
			reportDetailDAO.delete(reportDetails);

			List<ReportMarking> reportMarkings = reportMarkingDAO.find(ReportMarking.class, filter, null);
			reportMarkingDAO.delete(reportMarkings);

			List<ReportHistory> reportHistories = reportHistoryDAO.find(ReportHistory.class, filter, null);
			reportHistoryDAO.delete(reportHistories);

			Filter filter2 = new Filter();
			filter2.addRule(new FilterRule(FilterConstant.COLLECTION, "reportId", ids));
			List<ReportUnit> reportUnits = reportUnitDAO.find(ReportUnit.class, filter2, null);
			reportUnitDAO.delete(reportUnits);

			filter.getRules().clear();
			filter.addRule(new FilterRule(FilterConstant.COLLECTION, "id", ids));

			List<Report> reports = reportDAO.find(Report.class, filter, null);
			reportDAO.delete(reports);
		}
	}

	/**
	 * 根据操作人判断当前机构是否最高级别
	 * @param userOperatorId
	 * @return boolean
	 * */
	public boolean checkOperatorIsBest(String userOperatorId) {
		String sql = "select count(*)  from TBL_UNIT_RELATION tur where exists (select id  from tbl_user tu where tu.id = @userOperatorId  and tu.user_unit = tur.cid)";
		Map params = new HashMap();
		params.put("userOperatorId", userOperatorId);
		Integer count = sqlTemplate.queryForInt(sql, params);
		return (count == 1) ? true : false;
	}

	public String submitReport(cn.com.generaldata.os.pojo.mvc.Report report) {
		String id = null;
		if (StringUtils.isNotBlank(report.getReportId())) {
			String submitText = "提交待审核";
			id = report.getReportId();
			report.setCheckStatus(ReportConstant.FLAG_PROVINCE_PASSED_COMMITTED);
			// 如果是本级海洋局用户提交直接提交上级(内网肯定是海洋局用户填报),外网代填正相反
			if (checkOperatorIsBest(report.getReportProxyId()) || checkOperatorIsBest(report.getReportOperatorId())) {
				submitText = "审核通过";
			}
			report.setUpdateTime(new Date());
			modifyMVCReport(report);

			User operator = new User();
			operator.setId(report.getReportOperatorId());
			User user = userDAO.get(User.class, report.getReportOperatorId());
			cn.com.generaldata.os.pojo.Report reportPojo = this.queryReportById(report.getReportId());
			ReportUnit ru = new ReportUnit();
			DetachedCriteria dc = DetachedCriteria.forClass(ReportUnit.class);
			dc.add(Restrictions.eq("reportId", report.getReportId()));
			dc.add(Restrictions.eq("unitId", user.getUserUnit().getId()));
			List<ReportUnit> list = reportUnitDAO.findByCriteria(dc);
			if (list != null && list.size() > 0) {
				ru = list.get(0);
				ru.setCheckStatus(Short.valueOf(report.getCheckStatus()));
				reportUnitDAO.update(ru);
			} else {
				ru = new ReportUnit(report.getReportId(), user.getUserUnit().getId(), report.getReportAreaId(),
						Short.valueOf(report.getCheckStatus()));
				if (ru.getId() == null || "".equals(ru.getId()))
					ru.setId(UUID.randomUUID().toString().replaceAll("-", ""));
				reportUnitDAO.save(ru);
			}
			// 记录审核历史操作
			ReportHistory history = new ReportHistory(UUID.randomUUID().toString().replaceAll("-", ""), operator,
					reportPojo, report.getCheckStatus(), null, submitText, new Date());
			historyService.buildHistory(history);
		} else {
			String submitText = "提交待审核";
			report.setCheckStatus(ReportConstant.FLAG_PROVINCE_PASSED_COMMITTED);
			// 如果是本级海洋局用户提交直接提交上级(内网肯定是海洋局用户填报,外网正相反)
			if (!report.getReportOperatorId().equals(report.getReportUserId())) {
				if (checkOperatorIsBest(report.getReportOperatorId()))
					submitText = "审核通过";
			}
			id = createMVCReport(report);
			report.setReportId(id);
			// webservice调用开始
			//			ModelSend mo = new ModelSend();
			//			mo.setObj(report);
			//			mo.setFlag("7");
			//			new Thread(mo).start();
			// webservice调用结束

			User operator = new User();
			operator.setId(report.getReportOperatorId());
			User user = userDAO.get(User.class, report.getReportOperatorId());
			cn.com.generaldata.os.pojo.Report reportPojo = this.queryReportById(report.getReportId());
			ReportUnit ru = new ReportUnit();
			DetachedCriteria dc = DetachedCriteria.forClass(ReportUnit.class);
			dc.add(Restrictions.eq("reportId", report.getReportId()));
			dc.add(Restrictions.eq("unitId", user.getUserUnit().getId()));
			List<ReportUnit> list = reportUnitDAO.findByCriteria(dc);
			if (list != null && list.size() > 0) {
				ru = list.get(0);
				ru.setCheckStatus(Short.valueOf(report.getCheckStatus()));
				reportUnitDAO.update(ru);
			} else {
				ru = new ReportUnit(report.getReportId(), user.getUserUnit().getId(), report.getReportAreaId(),
						Short.valueOf(report.getCheckStatus()));
				if (ru.getId() == null || "".equals(ru.getId()))
					ru.setId(UUID.randomUUID().toString().replaceAll("-", ""));
				reportUnitDAO.save(ru);
			}
			// 记录审核历史操作
			ReportHistory history = new ReportHistory(UUID.randomUUID().toString().replaceAll("-", ""), operator,
					reportPojo, report.getCheckStatus(), null, submitText, new Date());
			historyService.buildHistory(history);
		}

		// 进行留痕操作
		// markReport(id, report.getCheckStatus());

		return id;
	}

	public void saveReportUtil(String reportId, String unitId, Short checkStatus, String areaId) {
		ReportUnit ru = new ReportUnit();
		DetachedCriteria dc = DetachedCriteria.forClass(ReportUnit.class);
		dc.add(Restrictions.eq("reportId", reportId));
		dc.add(Restrictions.eq("unitId", unitId));
		List<ReportUnit> list = reportUnitDAO.findByCriteria(dc);
		if (list != null && list.size() > 0) {
			ru = list.get(0);
			ru.setCheckStatus(checkStatus);
			reportUnitDAO.update(ru);
		} else {
			ru = new ReportUnit(reportId, unitId, areaId, checkStatus);
			if (ru.getId() == null || "".equals(ru.getId()))
				ru.setId(UUID.randomUUID().toString().replaceAll("-", ""));
			reportUnitDAO.save(ru);
		}
	}

	public List<ReportUnit> queryReportUnit(Filter filter) {
		List<ReportUnit> reports = reportUnitDAO.find(ReportUnit.class, filter, null);
		return reports;
	}

	public void passReport(cn.com.generaldata.os.pojo.mvc.Report reportMVC, String operatorId, Short checkStatus,
			String checkComment, String checkResult) {
		if (reportMVC == null || StringUtils.isBlank(operatorId)) {
			// throw new
			// CommonException(ExceptionConstant.MSG_ILLEGAL_PARAMETER);
			return;
		}

		Report report = queryReportById(reportMVC.getReportId());
		if (report == null) {
			// throw new CommonException(ExceptionConstant.MSG_REPORT_IS_NULL);
			return;
		}

		User operator = new User();
		operator.setId(operatorId);
		User user = userDAO.get(User.class, operatorId);
		User reportUser = userDAO.get(User.class, reportMVC.getReportOperatorId());
		// 报表操作者的地区ID
		String areaId = reportUser.getArea().getId();
		// 当前用户地区的上级ID
		Area area = user.getArea();
		String parentId = area.getParentId();
		// 如果当前用户不是报表的最后操作者
		if (!reportUser.getUserUnit().getId().equals(user.getUserUnit().getId())) {
			// throw new CommonException(ExceptionConstant.MSG_OPERATOR_IS_GO);
			return;
		}
		report.setOperator(operator);
		report.setReportCheckStatus(checkStatus);
		report.setReportCheckComment(checkComment);

		report.setReportCheckSuccessDate(new Date());

		modifyReport(report);

		// webservice调用开始
		//		ModelSend mo = new ModelSend();
		//		mo.setObj(report);
		//		mo.setFlag("2");
		//		new Thread(mo).start();
		// webservice调用结束

		// 进行留痕操作
		// markReport(reportId, checkStatus.byteValue());
		ReportUnit ru = new ReportUnit();
		DetachedCriteria dc = DetachedCriteria.forClass(ReportUnit.class);
		dc.add(Restrictions.eq("reportId", reportMVC.getReportId()));
		dc.add(Restrictions.eq("unitId", user.getUserUnit().getId()));
		List<ReportUnit> list = reportUnitDAO.findByCriteria(dc);
		if (list != null && list.size() > 0) {
			ru = list.get(0);
			ru.setCheckStatus(checkStatus);
			reportUnitDAO.update(ru);
		} else {
			ru = new ReportUnit(reportMVC.getReportId(), user.getUserUnit().getId(), report.getArea().getId(),
					checkStatus);
			if (ru.getId() == null || "".equals(ru.getId()))
				ru.setId(UUID.randomUUID().toString().replaceAll("-", ""));
			reportUnitDAO.save(ru);
		}
		// 记录审核历史操作
		ReportHistory history = new ReportHistory(UUID.randomUUID().toString().replaceAll("-", ""), operator, report,
				checkStatus, checkComment, "终审通过", new Date());
		historyService.buildHistory(history);
	}

	public void saveAudit(cn.com.generaldata.os.pojo.mvc.Report reportMVC, String operatorId, Short checkStatus,
			String checkComment) {
		String CheckResult = "";
		if (reportMVC == null || StringUtils.isBlank(operatorId)) {
			// throw new
			// CommonException(ExceptionConstant.MSG_ILLEGAL_PARAMETER);
			return;
		}

		Report report = queryReportById(reportMVC.getReportId());

		if (report == null) {
			// throw new
			// CommonException(ExceptionConstant.MSG_ILLEGAL_PARAMETER);
			return;
		}
		User operator = new User();
		operator.setId(operatorId);
		User user = userDAO.get(User.class, operatorId);
		User reportUser = userDAO.get(User.class, reportMVC.getReportOperatorId());
		// 报表操作者的地区ID的上级
		String areaId = reportUser.getArea().getParentId();
		// 当前用户地区的上级ID
		Area area = user.getArea();
		String parentId = area.getId();
		// 如果当前用户是报表的最后操作者，或报表最后操作者是当前用户的下级且报表状态为终身通过，当前用户才能初审
		// if(!report.getOperator().getId().equals(operatorId))
		// if (!reportMVC.getReportOperatorId().equals(operatorId)
		// && !(areaId.equals(parentId) &&
		// Short.valueOf(ReportConstant.FLAG_PROVINCE_PASSED_COMMITTED) ==
		// report
		// .getReportCheckStatus())) {
		// // throw new CommonException(ExceptionConstant.MSG_OPERATOR_IS_GO);
		// return;
		// }
		report.setOperator(operator);

		report.setReportCheckStatus(checkStatus);

		report.setReportCheckComment(checkComment);

		modifyReport(report);

		// webservice调用开始
		//		ModelSend mo = new ModelSend();
		//		mo.setObj(report);
		//		mo.setFlag("2");
		//		new Thread(mo).start();
		// webservice调用结束

		if (report.getReportCheckStatus() == 55) {
			CheckResult = "初审通过，等待终审";
		} else if (report.getReportCheckStatus() == 33) {
			CheckResult = "初审驳回，进入待驳回";
		}
		ReportUnit ru = new ReportUnit();
		DetachedCriteria dc = DetachedCriteria.forClass(ReportUnit.class);
		dc.add(Restrictions.eq("reportId", reportMVC.getReportId()));
		dc.add(Restrictions.eq("unitId", user.getUserUnit().getId()));
		List<ReportUnit> list = reportUnitDAO.findByCriteria(dc);
		if (list != null && list.size() > 0) {
			ru = list.get(0);
			ru.setCheckStatus(checkStatus);
			reportUnitDAO.update(ru);
		} else {
			ru = new ReportUnit(reportMVC.getReportId(), user.getUserUnit().getId(), report.getArea().getId(),
					checkStatus);
			if (ru.getId() == null || "".equals(ru.getId()))
				ru.setId(UUID.randomUUID().toString().replaceAll("-", ""));
			reportUnitDAO.save(ru);
		}
		// 记录审核历史操作
		ReportHistory history = new ReportHistory(UUID.randomUUID().toString().replaceAll("-", ""), operator, report,
				report.getReportCheckStatus(), report.getReportCheckComment(), CheckResult, new Date());
		historyService.buildHistory(history);
	}

	public Result queryReportTypeByHql(String hql, HashMap map, Page page) {
		return reportTypeDAO.hqlParam(hql, map, page);
	}

	public void removeReportAttachs(String[] ids) {
		Properties properties = new Properties();
		java.io.InputStream inputstream = getClass().getResourceAsStream("/fileupload.properties");
		try {
			properties.load(inputstream);
		} catch (Exception ex) {
			log.error("配置文件有误", ex);
		}
		ReportAttach reportAttach = new ReportAttach();
		if (ids != null && ids.length > 0) {
			for (String id : ids) {
				Filter filter = new Filter();
				filter.addRule(new FilterRule(FilterConstant.EQUAL, "attachId", id));
				List<ReportAttach> reportAttachs = reportAttachDAO.find(ReportAttach.class, filter, null);
				if (reportAttachs.size() > 0) {
					reportAttach = reportAttachs.get(0);

					File file = new File(properties.getProperty("fileUploadPath").trim()
							+ reportAttach.getAttachPathname());
					if (file.exists() && file.isFile()) {
						file.delete();
					}
					reportAttachDAO.delete(reportAttach);
				}
				filter.getRules().clear();
			}
		}
	}

	// 查询报表列表

	public Result queryReportAttach(Filter filter, Page page) {
		List<ReportAttach> reportAttachs = reportAttachDAO.find(ReportAttach.class, filter, page);
		int count = reportAttachDAO.count(ReportAttach.class, filter);

		if (page == null) {
			return new Result(1, 1, count, reportAttachs, new ArrayList<Event>());
		}
		return new Result(page.getPageNumber(), page.getPageSize(), count, reportAttachs, new ArrayList<Event>());
	}

	public Result queryReportAttachByHql(String hql, HashMap map, Page page) {
		return reportAttachDAO.hqlParam(hql, map, page);
		// int count = reportAttachDAO.count(ReportAttach.class, filter);
		//
		// if (page == null) {
		// return new Result(1, 1, count, reportAttachs, new
		// ArrayList<Event>());
		// }
		// return new Result(page.getPageNumber(), page.getPageSize(), count,
		// reportAttachs, new ArrayList<Event>());
	}

	// 按ID查找附件

	public ReportAttach queryReportAttachById(String id) {
		ReportAttach reportAttachs = reportAttachDAO.get(ReportAttach.class, id);

		return reportAttachs;
	}

	// 添加附件文件

	public String addReportAttachments(ReportAttach reportAttach) {
		if (reportAttach.getAttachId() == null || "".equals(reportAttach.getAttachId()))
			reportAttach.setAttachId(UUID.randomUUID().toString().replaceAll("-", ""));
		this.reportAttachDAO.save(reportAttach);
		return reportAttach.getAttachId();

	}

	public List<Report> queryReportsByBillboar(String typeCode, String timeType, String yearType, String quarterDate,
			String billboardTime, String reportVersion, String user) {
		String vSystem;
		String yearValue;
		String reportYearTime = null;
		String monthValue;
		String upYearValue;
		String upMonthValue;
		List<Report> reports = new ArrayList<Report>();
		if (billboardTime == null || "".equals(billboardTime)) {
			billboardTime = sfd.format(new Date());
		}
		String monthVlaue = billboardTime;
		Filter filter = new Filter();
		User user2 = userDAO.get(User.class, user);
		Filter filterU = new Filter();
		filterU.addRule(new FilterRule(FilterConstant.EQUAL, "userUnit.id", user2.getUserUnit().getId()));
		// 该单位的所有用户
		List<User> users = userDAO.find(User.class, filterU, null);
		String[] uids = new String[users.size()];
		for (int i = 0; i < users.size(); i++) {
			uids[i] = users.get(i).getId();
		}
		if (!(users.size() > 0)) {
			uids = new String[] { "" };
		}
		// List<String> uids=new ArrayList<String>();
		// for(User u:users)
		// uids.add(u.getId());
		filter.addRule(new FilterRule(FilterConstant.COLLECTION, "user.id", uids));
		// 月报
		if (timeType.equals("0")) {
			filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportMonth", billboardTime));
			filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportTimetype", timeType));
			filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportTypeId", typeCode));
			reports = reportDAO.find(Report.class, filter, null);
		}
		// 年报
		if (timeType.equals("1")) {
			yearValue = billboardTime.substring(0, 4);
			monthValue = billboardTime.substring(5);
			if (yearType.equals("1") || yearType.equals("4")) { // 半年报（实际没有4）
				// 2013/04
				if (Integer.valueOf(monthValue) > 6) {
					reportYearTime = "1"; // (上半年报)
					filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportYear", yearValue));
					filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportYearTime", reportYearTime));
					filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportTimetype", timeType));
				} else if (Integer.valueOf(monthValue) < 7) {
					// （去年全年报）
					filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportYear", String.valueOf(Integer
							.valueOf(yearValue) - 1)));
					filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportTimetype", "2"));
				}

				filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportTypeId", typeCode));
				reports = reportDAO.find(Report.class, filter, null);
			} else if (yearType.equals("2")) { // 全年报
				reportYearTime = "2";
				filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportYear", yearValue));
				// 全年报
				filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportYearTime", reportYearTime));

				filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportTimetype", timeType));
				filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportTypeId", typeCode));
				reports = reportDAO.find(Report.class, filter, null);
			}
		}
		// 季报
		if (timeType.equals("2")) {
			// 鑾峰彇褰撳墠鏃堕棿鐨勫勾浠�
			yearValue = billboardTime;
			if (quarterDate == null || !"".equals(quarterDate)) {
				Date parse = new Date();
				try {
					parse = sfd.parse(billboardTime);
				} catch (ParseException e) {
					// TODO Auto-generated catch block
					log.error("日期转换错误", e);
				}
				int month = parse.getMonth();
				if (month >= 0 && month < 3) {
					quarterDate = "第一季度";
				}
				if (month >= 3 && month < 6) {
					quarterDate = "第二季度";
				}
				if (month >= 6 && month < 9) {
					quarterDate = "第三季度";
				}
				if (month >= 9 && month < 12) {
					quarterDate = "第四季度";
				}
			}
			filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportYear", yearValue.substring(0, 4)));
			filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportQuarter", quarterDate));
			filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportTypeId", typeCode));
			reports = reportDAO.find(Report.class, filter, null);
		}
		if (reports.size() > 0) {
			return reports;
		} else {
			return null;
		}
	}

	/**
	 * 查询催报中已上报的报表
	 */

	public List<Report> queryReportsByBillboardUser(String typeCode, String timeType, String yearType,
			String quarterDate, String billboardTime, String reportVersion, String user) {
		String vSystem;
		String yearValue;
		String reportYearTime = null;
		String monthValue;
		String upYearValue;
		String upMonthValue;
		List<Report> reports = new ArrayList<Report>();
		if (billboardTime == null || "".equals(billboardTime)) {
			billboardTime = sfd.format(new Date());
		}
		// 鑾峰彇鎶ヨ〃鍒跺害瀵瑰簲鐨勭増鏈�
		// vSystem = reportVersion.substring(reportVersion.indexOf("(") + 1,
		// reportVersion.indexOf(")"));
		// Filter filter1 = new Filter();
		// filter1.setOrder(FilterConstant.DESC);
		// filter1.setSortBy("versionNumber");
		// if (StringUtils.isNotBlank(vSystem)) {
		// filter1.addRule(new FilterRule(FilterConstant.EQUAL, "versionName",
		// vSystem));
		// }
		// ReportVersion version = this.getVersion(filter1, null);
		String monthVlaue = billboardTime;
		Filter filter = new Filter();
		User user2 = userDAO.get(User.class, user);
		Filter filterU = new Filter();
		filterU.addRule(new FilterRule(FilterConstant.EQUAL, "userUnit.id", user2.getUserUnit().getId()));
		// 该单位的所有用户
		List<User> users = userDAO.find(User.class, filterU, null);
		String[] uids = new String[users.size()];
		for (int i = 0; i < users.size(); i++) {
			uids[i] = users.get(i).getId();
		}
		if (!(users.size() > 0)) {
			uids = new String[] { "" };
		}
		// List<String> uids=new ArrayList<String>();
		// for(User u:users)
		// uids.add(u.getId());
		filter.addRule(new FilterRule(FilterConstant.COLLECTION, "user.id", uids));
		// filter.addRule(new FilterRule(FilterConstant.EQUAL, "user.id",
		// user));
		// 月报
		if (timeType.equals("0")) {
			// // 获取上月数值
			// if (monthVlaue.substring(5, 7).equals("01")) { //
			// 第一年，要获取去年的年份并到去年12月
			// yearValue = billboardTime.substring(0, 4);
			// upYearValue = String.valueOf(Integer.parseInt(yearValue) - 1);
			// upMonthValue = upYearValue + "/12";
			// } else {
			// yearValue = billboardTime.substring(0, 4);
			// upMonthValue = String.valueOf(Integer.parseInt(monthVlaue
			// .substring(5, 7)) - 1);
			// if (upMonthValue.length() < 2)
			// upMonthValue = "0" + upMonthValue;
			// upMonthValue = yearValue + "/" + upMonthValue;
			// }
			filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportMonth", billboardTime));
			filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportTimetype", timeType));
			filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportTypeId", typeCode));
			filter.addRule(new FilterRule(FilterConstant.NOT_EQUAL, "reportCheckStatus", Short.valueOf("0")));
			// filter.addRule(new FilterRule(FilterConstant.EQUAL,
			// "reportVersion", version.getVersionNumber()));
			reports = reportDAO.find(Report.class, filter, null);
		}
		// 年报
		if (timeType.equals("1")) {
			yearValue = billboardTime.substring(0, 4);
			monthValue = billboardTime.substring(5);
			if (yearType.equals("1") || yearType.equals("4")) { // 半年报（实际没有4）
				// 2013/04
				if (Integer.valueOf(monthValue) > 6) {
					reportYearTime = "1"; // (上半年报)
					filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportYear", yearValue));
					filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportYearTime", reportYearTime));
					filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportTimetype", timeType));
				} else if (Integer.valueOf(monthValue) < 7) {
					// （去年全年报）
					filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportYear", String.valueOf(Integer
							.valueOf(yearValue) - 1)));
					filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportTimetype", "2"));
				}

				filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportTypeId", typeCode));
				filter.addRule(new FilterRule(FilterConstant.NOT_EQUAL, "reportCheckStatus", Short.valueOf("0")));
				// filter.addRule(new FilterRule(FilterConstant.EQUAL,
				// "reportVersion", version.getVersionNumber()));
				reports = reportDAO.find(Report.class, filter, null);
			} else if (yearType.equals("2")) { // 全年报
				reportYearTime = "2";
				filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportYear", yearValue));
				// 全年报
				filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportYearTime", reportYearTime));

				filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportTimetype", timeType));
				filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportTypeId", typeCode));
				filter.addRule(new FilterRule(FilterConstant.NOT_EQUAL, "reportCheckStatus", Short.valueOf("0")));
				// filter.addRule(new FilterRule(FilterConstant.EQUAL,
				// "reportVersion", version.getVersionNumber()));
				reports = reportDAO.find(Report.class, filter, null);
			}
			// else if (yearType.equals("3")) { //快报
			// reportYearTime = "3"; // 蹇勾鎶ユ椂鍒ゆ柇褰撳勾鏄惁瀛樺湪
			// filter.addRule(new FilterRule(FilterConstant.EQUAL,
			// "reportYear", yearValue.substring(0, 4)));
			// filter.addRule(new FilterRule(FilterConstant.EQUAL,
			// "reportYearTime", reportYearTime));
			// filter.addRule(new FilterRule(FilterConstant.EQUAL,
			// "reportTimetype", timeType));
			// filter.addRule(new FilterRule(FilterConstant.EQUAL,
			// "reportTypeId", typeCode));
			// filter.addRule(new FilterRule(FilterConstant.EQUAL,
			// "reportCheckStatus", Short.valueOf("1")));
			// // filter.addRule(new FilterRule(FilterConstant.EQUAL,
			// // "reportVersion", version.getVersionNumber()));
			// reports = reportDAO.find(Report.class, filter, null);
			// }
		}
		// 季报
		if (timeType.equals("2")) {
			// 鑾峰彇褰撳墠鏃堕棿鐨勫勾浠�
			yearValue = billboardTime;
			if (quarterDate == null || !"".equals(quarterDate)) {
				Date parse = new Date();
				try {
					parse = sfd.parse(billboardTime);
				} catch (ParseException e) {
					// TODO Auto-generated catch block
					log.error("日期转换错误", e);
				}
				int month = parse.getMonth();
				if (month >= 0 && month < 3) {
					quarterDate = "第一季度";
				}
				if (month >= 3 && month < 6) {
					quarterDate = "第二季度";
				}
				if (month >= 6 && month < 9) {
					quarterDate = "第三季度";
				}
				if (month >= 9 && month < 12) {
					quarterDate = "第四季度";
				}
			}
			filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportYear", yearValue.substring(0, 4)));
			filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportQuarter", quarterDate));
			// filter.addRule(new FilterRule(FilterConstant.EQUAL,
			// "reportTimetype", timeType));
			filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportTypeId", typeCode));
			filter.addRule(new FilterRule(FilterConstant.NOT_EQUAL, "reportCheckStatus", Short.valueOf("0")));
			// filter.addRule(new FilterRule(FilterConstant.EQUAL,
			// "reportVersion", version.getVersionNumber()));
			reports = reportDAO.find(Report.class, filter, null);
		}
		if (reports.size() > 0) {
			return reports;
		} else {
			return null;
		}
	}

	public void rejectReport(cn.com.generaldata.os.pojo.mvc.Report reportMVC, String operatorId, Short checkStatus,
			String checkComment, String checkResult) {
		if (reportMVC == null || StringUtils.isBlank(operatorId)) {
			// throw new
			// CommonException(ExceptionConstant.MSG_ILLEGAL_PARAMETER);
			return;
		}

		Report report = queryReportById(reportMVC.getReportId());
		if (report == null) {
			// throw new CommonException(ExceptionConstant.MSG_REPORT_IS_NULL);
			return;
		}

		User operator = new User();
		operator.setId(operatorId);
		User user = userDAO.get(User.class, operatorId);
		User reportUser = userDAO.get(User.class, reportMVC.getReportOperatorId());
		// 报表操作者的地区ID
		String areaId = reportUser.getArea().getId();
		// 当前用户地区的上级ID
		Area area = user.getArea();
		String parentId = area.getParentId();
		// 如果当前用户不是报表的最后操作者
		// if
		// (!reportUser.getUserUnit().getId().equals(user.getUserUnit().getId()))
		// {
		// // throw new CommonException(ExceptionConstant.MSG_OPERATOR_IS_GO);
		// return;
		// }
		report.setOperator(operator);

		report.setReportCheckStatus(checkStatus);

		// report.setReportCheckStatus(ReportConstant.FLAG_REJECTED);
		report.setReportCheckComment(checkComment);

		modifyReport(report);

		// webservice调用开始
		//		ModelSend mo = new ModelSend();
		//		mo.setObj(report);
		//		mo.setFlag("2");
		//		new Thread(mo).start();
		// webservice调用结束

		// 进行留痕操作
		// markReport(reportId, checkStatus.byteValue());
		ReportUnit ru = new ReportUnit();
		DetachedCriteria dc = DetachedCriteria.forClass(ReportUnit.class);
		dc.add(Restrictions.eq("reportId", reportMVC.getReportId()));
		dc.add(Restrictions.eq("unitId", user.getUserUnit().getId()));
		List<ReportUnit> list = reportUnitDAO.findByCriteria(dc);
		if (list != null && list.size() > 0) {
			ru = list.get(0);
			ru.setCheckStatus(checkStatus);
			reportUnitDAO.update(ru);
		} else {
			ru = new ReportUnit(reportMVC.getReportId(), user.getUserUnit().getId(), report.getArea().getId(),
					checkStatus);
			if (ru.getId() == null || "".equals(ru.getId()))
				ru.setId(UUID.randomUUID().toString().replaceAll("-", ""));
			reportUnitDAO.save(ru);
		}

		// 记录审核历史操作
		ReportHistory history = new ReportHistory(UUID.randomUUID().toString().replaceAll("-", ""), operator, report,
				checkStatus, checkComment, "终审驳回报表", new Date());
		historyService.buildHistory(history);
	}

	public String createReportDetail(ReportDetail reportDetail) {
		if (reportDetail != null) {
			Date date = new Date();
			reportDetail.setCreateTime(date);
			reportDetail.setLastEditTime(date);
			if (reportDetail.getId() == null || "".equals(reportDetail.getId()))
				reportDetail.setId(UUID.randomUUID().toString().replaceAll("-", ""));

			reportDetailDAO.save(reportDetail);
			return reportDetail.getId();
		}
		return null;
	}

	public ReportDetail modifyReportDetail(ReportDetail reportDetail) {
		if (reportDetail != null) {
			reportDetail.setLastEditTime(new Date());
			reportDetailDAO.update(reportDetail);
			return reportDetail;
		}
		return null;
	}

	public ReportDetail queryReportDetailById(String id) {
		if (id != null) {
			return reportDetailDAO.get(ReportDetail.class, id);
		}
		return null;
	}

	public Result queryReportDetails(Filter filter, Page page) {
		if (filter == null) {
			filter = new Filter();
		}
		if (StringUtils.isBlank(filter.getSortBy())) {
			filter.setSortBy("rowIndex");
			filter.setOrder(FilterConstant.ASC);
		}

		List<ReportDetail> reportDetails = reportDetailDAO.find(ReportDetail.class, filter, page);
		int count = reportDetailDAO.count(ReportDetail.class, filter);

		if (page == null) {
			return new Result(1, 1, count, reportDetails, new ArrayList<Event>());
		}
		return new Result(page.getPageNumber(), page.getPageSize(), count, reportDetails, new ArrayList<Event>());
	}

	public void removeReportDetails(String[] ids) {
		if (ids != null && ids.length > 0) {
			Filter filter = new Filter();
			filter.addRule(new FilterRule(FilterConstant.COLLECTION, "id", ids));

			List<ReportDetail> reportDetails = reportDetailDAO.find(ReportDetail.class, filter, null);
			reportDetailDAO.delete(reportDetails);
		}
	}

	public String createReportType(ReportType reportType) {
		if (reportType != null) {
			if (StringUtils.isNotBlank(reportType.getTypeName())) {
				ReportType oldReportType = checkReportTypeName(reportType.getTypeName());
				if (oldReportType != null) {
					// throw new CommonException(
					// ExceptionConstant.CODE_DUPLICATE_REPORT_TYPE_NAME,
					// ExceptionConstant.CAUSE_CREATE_REPORT_TYPE);
					log.error("oldReportType为空");
					return null;
				}
			}
			if (reportType.getId() == null || "".equals(reportType.getId()))
				reportType.setId(UUID.randomUUID().toString().replaceAll("-", ""));

			reportTypeDAO.save(reportType);
			return reportType.getId();
		}
		return null;
	}

	public ReportType modifyReportType(ReportType reportType) {
		if (reportType != null) {
			if (StringUtils.isNotBlank(reportType.getTypeName())) {
				ReportType oldReportType = checkReportTypeName(reportType.getTypeName());
				if (oldReportType != null && oldReportType.getId() != reportType.getId()) {
					// throw new
					// CommonException(ExceptionConstant.CODE_DUPLICATE_REPORT_TYPE_NAME,
					// ExceptionConstant.CAUSE_MODIFY_REPORT_TYPE);
					log.error("oldReportType为空");
					return null;
				}
			}

			reportTypeDAO.update(reportType);
			return reportType;
		}
		return null;
	}

	public ReportType queryReportTypeById(String id) {
		if (id != null) {
			return reportTypeDAO.get(ReportType.class, id);
		}
		return null;
	}

	public boolean isReportTimeType(User user, String typeCode, String timeType, String yearType, String timeValue,
			String quarterDate, String reportVersion) {
		String yearValue;
		List<Report> reports = new ArrayList<Report>();
		Calendar date = Calendar.getInstance();
		Filter filterU = new Filter();
		filterU.addRule(new FilterRule(FilterConstant.EQUAL, "userUnit.id", user.getUserUnit().getId()));
		// 该单位的所有用户
		List<User> users = userDAO.find(User.class, filterU, null);
		String[] uids = new String[users.size()];
		for (int i = 0; i < users.size(); i++) {
			uids[i] = users.get(i).getId();
		}
		if (!(users.size() > 0)) {
			uids = new String[] { "" };
		}
		// List<String> uids=new ArrayList<String>();
		// for(User u:users)
		// uids.add(u.getId());
		Filter filter = new Filter();
		// 对月报的判断，及timeType="0"
		if (timeType.equals("0")) {
			// 获取当前时间的月份，及timeType="0"
			// filter.addRule(new FilterRule(FilterConstant.EQUAL, "user.id",
			// user.getId()));
			filter.addRule(new FilterRule(FilterConstant.COLLECTION, "user.id", uids));
			filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportMonth", timeValue));
			filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportTimetype", timeType));
			filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportTypeId", typeCode));
			// filter.addRule(new FilterRule(FilterConstant.EQUAL,
			// "reportVersion", Float.valueOf(reportVersion)));
			reports = reportDAO.find(Report.class, filter, null);
		}
		if (timeType.equals("1")) {
			// 获取所选时间的年份
			yearValue = timeValue.substring(0, 4);
			int month = date.get(Calendar.MONTH);
			int year = date.get(Calendar.YEAR);
			if (yearType.equals("1")) { // 半年报
				// 查去年全年报
				if (month < 6) {
					filter.addRule(new FilterRule(FilterConstant.COLLECTION, "user.id", uids));
					// filter.addRule(new FilterRule(FilterConstant.EQUAL,
					// "user.id", user.getId()));
					filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportYear", String.valueOf(Integer
							.valueOf(yearValue) - 1)));
					filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportYearTime", "2"));
					filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportTimetype", timeType));
					filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportTypeId", typeCode));
					// filter.addRule(new FilterRule(FilterConstant.EQUAL,
					// "reportVersion", Float.valueOf(reportVersion)));
					reports = reportDAO.find(Report.class, filter, null);
				}
				// 查今年半年报
				else {
					filter.addRule(new FilterRule(FilterConstant.COLLECTION, "user.id", uids));
					// filter.addRule(new FilterRule(FilterConstant.EQUAL,
					// "user.id", user.getId()));
					filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportYear", String.valueOf(year)));
					filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportYearTime", "1"));
					filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportTimetype", timeType));
					filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportTypeId", typeCode));
					// filter.addRule(new FilterRule(FilterConstant.EQUAL,
					// "reportVersion", Float.valueOf(reportVersion)));
					reports = reportDAO.find(Report.class, filter, null);
				}

			} else if (yearType.equals("2")) { // 全年报

				filter.addRule(new FilterRule(FilterConstant.COLLECTION, "user.id", uids));
				// filter.addRule(new FilterRule(FilterConstant.EQUAL,
				// "user.id", user.getId()));
				filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportYear", String.valueOf(Integer
						.valueOf(yearValue))));
				filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportYearTime", "2"));
				filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportTimetype", timeType));
				filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportTypeId", typeCode));
				// filter.addRule(new FilterRule(FilterConstant.EQUAL,
				// "reportVersion", Float.valueOf(reportVersion)));
				reports = reportDAO.find(Report.class, filter, null);

			}
		}
		// 对季报的判断，及timeType="2"
		if (timeType.equals("2")) {
			// 获取当前时间的年份
			yearValue = timeValue.substring(0, 4);
			// filter.addRule(new FilterRule(FilterConstant.EQUAL, "user.id",
			// user.getId()));
			filter.addRule(new FilterRule(FilterConstant.COLLECTION, "user.id", uids));
			filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportYear", yearValue));
			filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportQuarter", quarterDate));
			filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportTimetype", timeType));
			filter.addRule(new FilterRule(FilterConstant.EQUAL, "reportTypeId", typeCode));
			// filter.addRule(new FilterRule(FilterConstant.EQUAL,
			// "reportVersion", Float.valueOf(reportVersion)));
			reports = reportDAO.find(Report.class, filter, null);
		}
		if (reports.size() > 0) {
			return true; // 表示存在
		} else {
			return false; // 表示不存在
		}
	}

	/**
	 * 指标汇总值
	 * 
	 * @param userRoleId
	 * @param userAreaId
	 * @param reportYear
	 * @param reportYearTime
	 * @param month
	 * @param quarter
	 * @param timeType
	 * @param reportTypeId
	 * @param checkStatus
	 * @param provinceUnitId
	 * @param rti
	 * @return
	 */
	public String sumIndicator(String userRoleId, String[] userAreaId, String reportYear, String reportYearTime,
			int month, int quarter, String timeType, String reportTypeId, Short checkStatus, String provinceUnitId,
			ReportTypeIndicator rti) {
		String sql = "SELECT SUM(rd.$clomun) FROM "
				+ " tbl_report r INNER JOIN tbl_report_detail rd ON r.id = rd.report_id "
				+ " INNER JOIN tbl_report_unit ru ON ru.report_id = r.id AND ru.operator_unit = @provinceUnitId AND ru.check_status = @checkStatus "
				+ " INNER JOIN tbl_user u ON r.report_user_id = u.id "
				+ " INNER JOIN tbl_unit unit ON u.user_unit = unit.id "
				+ " INNER JOIN tbl_area area ON unit.unit_area_id = area.id "
				+ " WHERE "
				+ " u.user_role_id = @userRoleId AND u.user_area_id in (@userAreaId) AND r.report_check_status = @checkStatus "
				+ " AND r.report_type_id = @reportTypeId " + " AND rd.row_index = @row ";
		Map<String, Object> param = Maps.newHashMap();
		// 当前时间
		Calendar date = Calendar.getInstance();
		int monthValue = date.get(Calendar.MONTH);
		if (Integer.valueOf(timeType) == Constants.REPORT_TIME_MONTH) {
			sql += " AND r.report_timetype = @reportTimetype AND r.report_year = @reportYear AND r.month = @month ";
			param.put("month", month);

		} else if (Integer.valueOf(timeType) == Constants.REPORT_TIME_YEAR) {
			// 全年报时，获取去年的上报记录
			if (reportYearTime.equals("2")) {

				reportYearTime = "2";

			} else if (reportYearTime.equals("1")) { // 半年报
				// 获取去年的上报记录
				if (monthValue < 6) {
					reportYearTime = "2";
					reportYear = String.valueOf(Integer.valueOf(reportYear) - 1);
				}
				// 查今年半年
				else {
					// 首先获取当前年的第一次上报记录
					reportYearTime = "1";
				}
			}
			sql += " AND r.report_timetype = @reportTimetype AND r.report_year = @reportYear AND r.report_year_time = @reportYearTime ";
			param.put("reportYearTime", reportYearTime);

		} else {
			sql += " AND r.report_timetype = @reportTimetype AND r.report_year = @reportYear AND r.quarter = @quarter ";
			param.put("quarter", quarter);
		}
		param.put("provinceUnitId", provinceUnitId);
		param.put("reportTypeId", reportTypeId);
		param.put("reportTimetype", timeType + "");
		param.put("reportYear", reportYear);
		param.put("checkStatus", checkStatus);
		param.put("userRoleId", userRoleId);
		param.put("userAreaId", userAreaId);
		param.put("row", rti.getRow());
		Map<String, Object> vars = Maps.newHashMap();
		vars.put("clomun", "f" + rti.getTheColumn().intValue());

		Double result = sqlTemplate.queryForObject(sql, vars, param, Double.class);
		if (result == null) {
			return null;
		}
		return String.format("%.2f", result);
	}

	/**
	 * 同级涉海部门指标值
	 * 
	 * @param unitId
	 * @param reportYear
	 * @param reportYearTime
	 * @param month
	 * @param quarter
	 * @param timeType
	 * @param reportTypeId
	 * @param checkStatus
	 * @param provinceUnitId
	 * @param rti
	 * @return
	 */
	public String departIndicator(String unitId, String reportYear, String reportYearTime, int month, int quarter,
			String timeType, String reportTypeId, Short checkStatus, String provinceUnitId, ReportTypeIndicator rti) {
		String sql = "SELECT rd.$clomun FROM "
				+ " tbl_report r INNER JOIN tbl_report_detail rd ON r.id = rd.report_id "
				+ " INNER JOIN tbl_report_unit ru ON ru.report_id = r.id AND ru.operator_unit = @provinceUnitId AND ru.check_status = @checkStatus "
				+ " INNER JOIN tbl_user u ON r.report_user_id = u.id "
				+ " INNER JOIN tbl_unit unit ON u.user_unit = unit.id "
				+ " INNER JOIN tbl_area area ON unit.unit_area_id = area.id " + " WHERE "
				+ " u.user_role_id = '5' AND u.user_unit = @unitId AND r.report_check_status = @checkStatus "
				+ " AND r.report_type_id = @reportTypeId " + " AND rd.row_index = @row ";
		Map<String, Object> param = Maps.newHashMap();
		// 当前时间
		Calendar date = Calendar.getInstance();
		int monthValue = date.get(Calendar.MONTH);
		if (Integer.valueOf(timeType) == Constants.REPORT_TIME_MONTH) {
			sql += " AND r.report_timetype = @reportTimetype AND r.report_year = @reportYear AND r.month = @month ";
			param.put("month", month);

		} else if (Integer.valueOf(timeType) == Constants.REPORT_TIME_YEAR) {
			// 全年报
			if (reportYearTime.equals("2")) {

				reportYearTime = "2";

			} else if (reportYearTime.equals("1")) { // 半年报
				// 获取去年的上报记录
				if (monthValue < 6) {
					reportYearTime = "2";
					reportYear = String.valueOf(Integer.valueOf(reportYear) - 1);
				}
				// 查今年半年
				else {
					// 首先获取当前年的第一次上报记录
					reportYearTime = "1";
				}
			}
			sql += " AND r.report_timetype = @reportTimetype AND r.report_year = @reportYear AND r.report_year_time = @reportYearTime ";
			param.put("reportYearTime", reportYearTime);

		} else {
			sql += " AND r.report_timetype = @reportTimetype AND r.report_year = @reportYear AND r.quarter = @quarter ";
			param.put("quarter", quarter);
		}
		param.put("provinceUnitId", provinceUnitId);
		param.put("reportTypeId", reportTypeId);
		param.put("reportTimetype", timeType + "");
		param.put("reportYear", reportYear);
		param.put("checkStatus", checkStatus);
		param.put("unitId", unitId);
		param.put("row", rti.getRow());
		Map<String, Object> vars = Maps.newHashMap();
		vars.put("clomun", "f" + rti.getTheColumn().intValue());

		String result = sqlTemplate.queryForObject(sql, vars, param, String.class);

		return result;
	}

	/**
	 * 行式报表汇总
	 * 
	 * @param unitId
	 * @param reportYear
	 * @param reportYearTime
	 * @param month
	 * @param quarter
	 * @param timeType
	 * @param reportTypeId
	 * @param checkStatus
	 * @param provinceUnitId
	 * @param rti
	 * @return
	 */
	public List<Row> sumRows(String[] unitId, String reportYear, String reportYearTime, int month, int quarter,
			String timeType, String reportTypeId, Short checkStatus, String provinceUnitId) {
		String sql = "SELECT rd.* FROM "
				+ " tbl_report_detail rd INNER JOIN tbl_report r ON r.id = rd.report_id "
				+ " INNER JOIN tbl_report_unit ru ON ru.report_id = r.id AND ru.operator_unit = @provinceUnitId AND ru.check_status = @checkStatus "
				+ " INNER JOIN tbl_user u ON r.report_user_id = u.id "
				+ " INNER JOIN tbl_unit unit ON u.user_unit = unit.id "
				+ " INNER JOIN tbl_area area ON unit.unit_area_id = area.id " + " WHERE "
				+ " u.user_unit in (@unitId) AND r.report_check_status = @checkStatus "
				+ " AND r.report_type_id = @reportTypeId ";
		Map<String, Object> param = Maps.newHashMap();
		// 当前时间
		Calendar date = Calendar.getInstance();
		int monthValue = date.get(Calendar.MONTH);
		if (Integer.valueOf(timeType) == Constants.REPORT_TIME_MONTH) {
			sql += " AND r.report_timetype = @reportTimetype AND r.report_year = @reportYear AND r.month = @month ";
			param.put("month", month);

		} else if (Integer.valueOf(timeType) == Constants.REPORT_TIME_YEAR) {
			// 全年报时，获取去年的上报记录
			if (reportYearTime.equals("2")) {

				// 查全年报
				reportYearTime = "2";

			} else if (reportYearTime.equals("1")) { // 半年报
				// 查全年
				if (monthValue < 6) {
					reportYearTime = "2";
					reportYear = String.valueOf(Integer.valueOf(reportYear) - 1);
				}
				// 查今年半年
				else {
					// 首先获取当前年的第一次上报记录
					reportYearTime = "1";
				}
			}
			sql += " AND r.report_timetype = @reportTimetype AND r.report_year = @reportYear AND r.report_year_time = @reportYearTime ";
			param.put("reportYearTime", reportYearTime);
		} else {
			sql += " AND r.report_timetype = @reportTimetype AND r.report_year = @reportYear AND r.quarter = @quarter ";
			param.put("quarter", quarter);
		}
		param.put("provinceUnitId", provinceUnitId);
		param.put("reportTypeId", reportTypeId);
		param.put("reportTimetype", timeType + "");
		param.put("reportYear", reportYear);
		param.put("checkStatus", checkStatus);
		param.put("unitId", unitId);
		Entity<cn.com.generaldata.jsme_indicator_system.entity.ReportDetail> entity = indicatorSystemDao
				.getEntity(cn.com.generaldata.jsme_indicator_system.entity.ReportDetail.class);
		List<cn.com.generaldata.jsme_indicator_system.entity.ReportDetail> list = sqlTemplate.query(sql, param, entity);
		List<Row> rows = new ArrayList<Row>();
		for (int i = 0, size = list.size(); i < size; i++) {
			Row row = new Row();
			cn.com.generaldata.jsme_indicator_system.entity.ReportDetail detail = list.get(i);
			row = BeanMapper.map(detail, Row.class);
			row.setRowId(detail.getId());
			row.setRowType(Row.ROW_TYPE_ACCOUNT);
			rows.add(row);
		}
		return rows;
	}

	/**
	 * 行式报表汇总
	 * 
	 * @param user
	 * @param reportType
	 * @param timeDate
	 * @param quarter
	 * @return
	 */

	public List<Row> getRowsAccounting(User user, ReportType reportType, String timeDate, int quarter) {
		String yearValue = "";
		String monthVlaue = "";
		List<Row> resultList = new ArrayList<Row>();
		// 填报人的身份
		Role role = user.getUserUnit().getRole();
		// 海洋局用户
		if (ReportConstant.OCEAN.equals(role.getId())) {
			Integer summarizationType = reportType.getDataSummarization();
			// 不用汇总
			if (summarizationType == null || summarizationType.intValue() != 1) {
				return resultList;
			}
			HashMap param = new HashMap();
			List<Unit> allUnit = new ArrayList<Unit>();
			// 下级海洋局
			String sql = "select * from tbl_unit where UNIT_ROLE_ID='" + ReportConstant.OCEAN
					+ "' and id in(select cid from TBL_UNIT_RELATION where pid=@unitId and DEPTH="
					+ ReportConstant.INTEGER_TYPE + ")";
			param.put("unitId", user.getUserUnit().getId());
			List<UnitNz> departList = sqlTemplate.query(sql, param, indicatorSystemDao.getEntity(UnitNz.class));
			for (UnitNz depart : departList) {
				Unit unit = new Unit();
				unit.setId(depart.getId());
				allUnit.add(unit);
			}
			// 下级涉海部门
			sql = "select * from tbl_unit where UNIT_ROLE_ID='" + ReportConstant.SHEHAI_BUMEN
					+ "' and id in(select cid from TBL_UNIT_RELATION where pid=@unitId and DEPTH="
					+ ReportConstant.LONG_TYPE + ")";
			List<UnitNz> departList2 = sqlTemplate.query(sql, param, indicatorSystemDao.getEntity(UnitNz.class));
			for (UnitNz depart : departList2) {
				Unit unit = new Unit();
				unit.setId(depart.getId());
				allUnit.add(unit);
			}
			// 本级涉海部门
			sql = "select * from tbl_unit where UNIT_ROLE_ID='" + ReportConstant.SHEHAI_BUMEN
					+ "' and id in(select cid from TBL_UNIT_RELATION where pid=@unitId and DEPTH="
					+ ReportConstant.INTEGER_TYPE + ")";
			List<UnitNz> departList3 = sqlTemplate.query(sql, param, indicatorSystemDao.getEntity(UnitNz.class));
			for (UnitNz depart : departList3) {
				Unit unit = new Unit();
				unit.setId(depart.getId());
				allUnit.add(unit);
			}
			// 河北省海洋局
			Filter unitfilter = new Filter();
			unitfilter.addRule(new FilterRule(FilterConstant.EQUAL, "role.id", ReportConstant.OCEAN));
			unitfilter.addRule(new FilterRule(FilterConstant.EQUAL, "area.id", ReportConstant.PROVINCE_AREA_ID));
			List<Unit> unitList = unitDAO.find(Unit.class, unitfilter, null);
			Unit unit = unitList.get(0);
			// 频率
			String timeType = reportType.getTypeTime();
			// 年报类别
			String yearType = reportType.getTypeYearTime();
			yearValue = timeDate.substring(0, 4);
			monthVlaue = timeDate.substring(5, 7);
			int month = Integer.valueOf(monthVlaue);
			Integer dataType = reportType.getDataType();
			// 单位ID
			String[] unitIds = new String[allUnit.size()];
			for (int j = 0; j < allUnit.size(); j++) {
				unitIds[j] = allUnit.get(j).getId();
			}
			if (!(allUnit.size() > 0)) {
				unitIds = new String[] { "" };
			}
			// 行式报表
			if (dataType == 2) {
				resultList = sumRows(unitIds, yearValue, yearType, month, quarter, timeType, reportType.getId(),
						Short.valueOf(ReportConstant.FLAG_PROVINCE_PASSED_COMMITTED), unit.getId());
			}
		}
		return resultList;
	}

	public Map getReportIndicator(User user, ReportType reportType, Date timeDate, int quarter, Map accounting) {
		// 获取该报表有关联的指标
		String sql2 = "SELECT ir.* FROM t_indicator_relation ir, tbl_report_type rt,t_report_type_indicator rtip WHERE rtip.report_type_id = rt.id AND"
				+ " ir.source_indicator_stat_system = rt.stat_system AND ir.source_indicator_id=rtip.indicator_id AND rt.id = @reportId ";
		Map<String, Object> param = Maps.newHashMap();
		param.put("reportId", reportType.getId());
		Entity<IndicatorRelation> entity = indicatorSystemDao.getEntity(IndicatorRelation.class);
		List<IndicatorRelation> indicatorRelations = indicatorSystemSqlTemplate.query(sql2, param, entity);
		// 取该单位所有用户
		Filter filterU = new Filter();
		Unit userUnit = user.getUserUnit();
		filterU.addRule(new FilterRule(FilterConstant.EQUAL, "userUnit.id", userUnit.getId()));
		// 该单位的所有用户
		List<User> users = userDAO.find(User.class, filterU, null);
		String[] uids = new String[users.size()];
		for (int i = 0; i < users.size(); i++) {
			uids[i] = users.get(i).getId();
		}
		if (!(users.size() > 0)) {
			uids = new String[] { "" };
		}
		for (IndicatorRelation relation : indicatorRelations) {
			Map<String, Object> params = Maps.newHashMap();
			Map<String, Object> vars = Maps.newHashMap();
			ReportTypeIndicator indicatorRel = getReportTypeIndicatorRel(timeDate, relation.getTargetIndicatorId(),
					relation.getTargetIndicatorStatSystem());
			if (indicatorRel == null) {
				log.error("无法获取指标与报表的关系，引用指标信息：{},其他条件：{}", relation.getTargetIndicatorId(), reportType.getStatSystem());
				continue;
			} else {

				String reportTypeId = indicatorRel.getReportTypeId();
				// 换算时间频率
				ReportTimeVO reportTimeVO = frequencyConverter(reportType, reportTypeId, sfd.format(timeDate), quarter);
				if (reportTimeVO == null) {
					log.error("无法获取指标与报表的关系，引用指标信息：{},其他条件：{}", relation.getTargetIndicatorId(),
							reportType.getStatSystem());
					continue;
				}
				Integer row = indicatorRel.getRow();
				Integer clomun = indicatorRel.getTheColumn();

				params.put("reportTypeId", reportTypeId);
				if (row != null) {
					params.put("row", row);
				}
				vars.put("clomun", "f" + clomun.intValue());
				params.put("provinceUnitId", unitService.getProvinceOceanUnit().getId());
				params.put("reportTimetype", reportTimeVO.timeType);
				params.put("reportYear", reportTimeVO.year);
				String sql = "SELECT ";
				if (relation.getGetValueType() == GET_VALUE_TYPE_GET) {
					sql += " rd.$clomun ";
				} else {
					sql += " SUM(rd.$clomun) ";
				}
				sql += "FROM tbl_report r INNER JOIN tbl_report_detail rd ON r.id = rd.report_id "
						+ " INNER JOIN tbl_user u ON r.report_user_id = u.id "
						//暂时去掉省级终审通过
						//						+ " INNER JOIN tbl_report_unit ru ON ru.report_id = r.id AND ru.operator_unit = @provinceUnitId AND ru.check_status = '5' "
						+ " WHERE r.report_type_id = @reportTypeId  ";

				if (params.containsKey("row")) {
					sql += " AND rd.row_index = @row ";
				}
				// 取值时，直接取对应的地区id报表数据
				sql += " AND u.id in (@userId)";
				params.put("userId", uids);
				// 汇总时间频率条件SQL
				if (reportTimeVO.timeType == Constants.REPORT_TIME_MONTH) {
					sql += " AND r.report_timetype = @reportTimetype AND r.report_year = @reportYear AND r.month = @month ";
					params.put("month", reportTimeVO.month);
				} else if (reportTimeVO.timeType == Constants.REPORT_TIME_YEAR) {
					sql += " AND r.report_timetype = @reportTimetype AND r.report_year = @reportYear AND r.report_year_time = @reportYearTime ";
					params.put("reportYearTime", reportTimeVO.yearTime);
				} else {
					sql += " AND r.report_timetype = @reportTimetype AND r.report_year = @reportYear AND r.quarter = @quarter ";
					params.put("quarter", reportTimeVO.quarter);
				}
				// 引用指标值不存在，按0进行处理
				Double indicatorValue = null;
				try {
					indicatorValue = sqlTemplate.queryForObject(sql, vars, params, Double.class);
				} catch (Exception e) {
					log.error(String.format("获取核算指标引用的指标时发生错误，核算指标信息:" + relation.getTargetIndicatorId() + ",引用指标信息"),
							e);
				}
				if (indicatorValue != null) {
					// 统一数量级后指标值
					Double magnitude = reducingResultMagnitude(indicatorValue, relation);
					Map mapSea = (HashMap) accounting.get(relation.getSourceIndicatorId());
					if (mapSea == null) {
						mapSea = new HashMap();
						accounting.put(relation.getSourceIndicatorId(), mapSea);
					}
					mapSea.put(userUnit.getUnitName(), magnitude);
				}
			}
		}
		return accounting;
	}

	/**
	 * 将指标查询结果还原统一的数量级.
	 * 
	 * @param result
	 *            查询到的指标值
	 * @param reference
	 *            引用指标信息
	 * @return
	 */
	private Double reducingResultMagnitude(Double result, IndicatorRelation relation) {
		Double indicatotUnitMagnitude = 1d;
		Double indicatotUnitMagnitude2 = 1d;
		Cnd cnd = Cnd.where("id", "=", relation.getTargetIndicatorId()).and("indicator_type", "=",
				relation.getTargetIndicatorStatSystem());
		Record record = indicatorSystemDao.fetch("v_indicator_info", cnd);
		if (record != null) {
			if (record.get("unit_magnitude") != null) {
				indicatotUnitMagnitude = Castors.me().castTo(record.get("unit_magnitude"), Double.class);
			}
			Cnd cnd2 = Cnd.where("id", "=", relation.getSourceIndicatorId()).and("indicator_type", "=",
					relation.getSourceIndicatorStatSystem());
			Record record2 = indicatorSystemDao.fetch("v_indicator_info", cnd2);
			if (record2 != null) {
				if (record2.get("unit_magnitude") != null) {
					indicatotUnitMagnitude2 = Castors.me().castTo(record2.get("unit_magnitude"), Double.class);
				}
			}
		}
		return indicatotUnitMagnitude2 == 0 ? 0 : result * indicatotUnitMagnitude / indicatotUnitMagnitude2;
	}

	/**
	 * 原报表时间类型与目标报表时间类型转换.
	 * 
	 * @param reference
	 * @param indicatorAccountVO
	 */
	private ReportTimeVO frequencyConverter(ReportType reportType, String targetTypeId, String timeDate, int quarter) {
		ReportTimeVO reportTime = null;
		ReportType targetType = reportTypeDAO.get(ReportType.class, targetTypeId);
		// 目标
		int frequency = Integer.valueOf(targetType.getTypeTime());
		// 年
		String yearValue = timeDate.substring(0, 4);
		Integer year = Integer.valueOf(yearValue);
		// 月
		String monthValue = timeDate.substring(5, 7);
		Integer month = Integer.valueOf(monthValue);
		// 源年报
		if (Integer.valueOf(reportType.getTypeTime()) == Constants.REPORT_TIME_YEAR) {

			// 源半年报
			if (Integer.valueOf(reportType.getTypeYearTime()) == 1) {
				// 季报
				if (frequency == 2) {
					// 返回 类型 季报 季度为2
					reportTime = new ReportTimeVO(Constants.REPORT_TIME_QUARTER, year, null, 2, null);
				}
				// 月报
				else if (frequency == 0) {
					// 返回类型为 月报 月份为6
					reportTime = new ReportTimeVO(Constants.REPORT_TIME_MONTH, year, null, null, 6);

				} else {
					reportTime = new ReportTimeVO(Constants.REPORT_TIME_YEAR, year, 1, null, null);
				}

			} else {
				// 年报
				if (frequency == 2) {
					// 返回 类型 季报 季度为4
					reportTime = new ReportTimeVO(Constants.REPORT_TIME_QUARTER, year, null, 4, null);
				} else if (frequency == 0) {
					// 返回类型为 月报 月份为12
					reportTime = new ReportTimeVO(Constants.REPORT_TIME_MONTH, year, null, null, 12);
				} else {
					reportTime = new ReportTimeVO(Constants.REPORT_TIME_YEAR, year, 2, null, null);
				}
			}
		}
		// 源季报
		if (Integer.valueOf(reportType.getTypeTime()) == Constants.REPORT_TIME_QUARTER) {

			// 季报
			if (frequency == 2) {
				reportTime = new ReportTimeVO(Constants.REPORT_TIME_QUARTER, year, null, quarter, null);
			}
			// 月报
			else if (frequency == 0) {
				if (quarter == 1) {
					// 返回类型为 月报 月份为3
					reportTime = new ReportTimeVO(Constants.REPORT_TIME_MONTH, year, null, null, 3);
				} else if (quarter == 2) {
					// 返回类型为 月报 月份为6
					reportTime = new ReportTimeVO(Constants.REPORT_TIME_MONTH, year, null, null, 6);
				} else if (quarter == 3) {
					// 返回类型为 月报 月份为9
					reportTime = new ReportTimeVO(Constants.REPORT_TIME_MONTH, year, null, null, 9);
				} else if (quarter == 4) {
					// 返回类型为 月报 月份为12
					reportTime = new ReportTimeVO(Constants.REPORT_TIME_MONTH, year, null, null, 12);
				}
			} else {
				if (quarter == 2) {
					// 返回类型为 半年报
					reportTime = new ReportTimeVO(Constants.REPORT_TIME_YEAR, year, 1, null, null);
				} else if (quarter == 4) {
					// 返回类型为 全年
					reportTime = new ReportTimeVO(Constants.REPORT_TIME_YEAR, year, 2, null, null);
				}
			}
		}
		// 源月报
		if (Integer.valueOf(reportType.getTypeTime()) == Constants.REPORT_TIME_MONTH) {
			// 季报
			if (frequency == 2) {
				if (month == 3) {
					// 返回类型为 一季度
					reportTime = new ReportTimeVO(Constants.REPORT_TIME_MONTH, year, null, 1, null);
				} else if (month == 6) {
					// 返回类型为 二季度
					reportTime = new ReportTimeVO(Constants.REPORT_TIME_MONTH, year, null, 2, null);
				} else if (month == 9) {
					// 返回类型为 三季度
					reportTime = new ReportTimeVO(Constants.REPORT_TIME_MONTH, year, null, 3, null);
				} else if (month == 12) {
					// 返回类型为 四季度
					reportTime = new ReportTimeVO(Constants.REPORT_TIME_MONTH, year, null, 4, null);
				}

			} else if (frequency == 0) {
				reportTime = new ReportTimeVO(Constants.REPORT_TIME_MONTH, year, null, null, month);
			} else {
				if (month == 6) {
					// 返回类型为 半年报
					reportTime = new ReportTimeVO(Constants.REPORT_TIME_MONTH, year, 1, null, null);
				} else if (month == 12) {
					reportTime = new ReportTimeVO(Constants.REPORT_TIME_YEAR, year, 2, null, null);
				}
			}

		}
		return reportTime;
	}

	/**
	 * 获取报表与指标的关系.
	 * 
	 * @param reference
	 * @param indicatorAccountVO
	 * @param reportStatSystem
	 * @return
	 */
	private ReportTypeIndicator getReportTypeIndicatorRel(Date time, Integer indicatorId, Integer statSystem) {
		String sql = "SELECT rtip.* FROM t_report_type_indicator rtip INNER JOIN tbl_report_type rt ON rtip.report_type_id = rt.id "
				+ " INNER JOIN tbl_report_version rv "
				+ " ON rt.version_id = rv.id AND rv.start_date <= @year AND rv.end_date >= @year AND rv.stat_system = @statSystem "
				+ " WHERE rtip.indicator_id = @indicatorId";
		Map<String, Object> params = Maps.newHashMap();
		params.put("year", time);
		params.put("indicatorId", indicatorId);
		params.put("statSystem", statSystem);
		Entity<ReportTypeIndicator> entity = indicatorSystemDao.getEntity(ReportTypeIndicator.class);
		return indicatorSystemSqlTemplate.queryForObject(sql, params, entity);

	}

	/**
	 * 取得单元格式式报表上期的指标数值
	 * 
	 * @param user
	 * @param reportType
	 * @param timeDate
	 * @param quarterDate
	 * @return
	 */
	private Map getLasttimeCellReport(User user, ReportType reportType, String timeDate, String quarterDate) {
		HashMap map = new HashMap();
		Report reportByParam = getReportByParam(user, reportType, timeDate, quarterDate);
		if (reportByParam != null) {
			Report lasttimeReport = reportByParam;
			Filter reportFilter = new Filter();
			reportFilter.addRule(new FilterRule(FilterConstant.EQUAL, "report.id", lasttimeReport.getId()));
			reportFilter.setOrder(FilterConstant.ASC);
			reportFilter.setSortBy("rowIndex");
			List<ReportDetail> list = reportDetailDAO.find(ReportDetail.class, reportFilter, null);
			if (list != null && list.size() > 0) {
				String reportTypeId = lasttimeReport.getReportTypeId();
				Cnd cnd = Cnd.where("reportTypeId", "=", reportTypeId);
				List<ReportTypeIndicator> query = indicatorSystemDao.query(ReportTypeIndicator.class, cnd);
				for (ReportTypeIndicator rti : query) {
					Integer row = rti.getRow();
					if (row == null || row >= list.size()) {
						break;
					} else {
						ReportDetail rd = list.get(row.intValue());
						// for (ReportDetail rd : list) {
						Integer indicatorId = rti.getIndicatorId();
						Integer theColumn = rti.getTheColumn();
						// if(rd.getRowIndex()==row.intValue())
						// {
						String fieldName = "f" + theColumn;
						Object value = reportDetailMirror.getValue(rd, fieldName);
						map.put(indicatorId, value);
						// break;
						// }
						// }
					}
				}
			}
		}
		return map;
	}

	/**
	 * 取得行式式报表上期的指标数值
	 * 
	 * @param user
	 * @param reportType
	 * @param timeDate
	 * @param quarterDate
	 * @return
	 */
	private Map getLasttimeRowReport(User user, ReportType reportType, String timeDate, String quarterDate) {
		HashMap map = new HashMap();
		Report reportByParam = getReportByParam(user, reportType, timeDate, quarterDate);
		if (reportByParam != null) {

			Report lasttimeReport = reportByParam;
			Filter reportFilter = new Filter();
			reportFilter.addRule(new FilterRule(FilterConstant.EQUAL, "report.id", lasttimeReport.getId()));
			reportFilter.setOrder(FilterConstant.ASC);
			reportFilter.setSortBy("rowIndex");
			List<ReportDetail> list = reportDetailDAO.find(ReportDetail.class, reportFilter, null);
			if (list != null && list.size() > 0) {
				cn.com.generaldata.jsme_indicator_system.entity.ReportType rt = indicatorSystemDao.fetch(
						cn.com.generaldata.jsme_indicator_system.entity.ReportType.class, reportType.getId());
				String reportTypeId = lasttimeReport.getReportTypeId();
				List<Integer> numbericIndicatorId = getNumbericIndicator(reportType.getId());
				for (Integer indicatorId : numbericIndicatorId) {

					Cnd cnd = Cnd.where("reportTypeId", "=", reportTypeId).and("indicatorId", "=", indicatorId);

					ReportTypeIndicator rti = indicatorSystemDao.fetch(ReportTypeIndicator.class, cnd);
					Map<String, String> indicatorValMap = Maps.newHashMap();

					for (ReportDetail rd : list) {
						Integer theColumn = rti.getTheColumn();
						String fieldName = "f" + theColumn;
						String indicatorValue = (String) reportDetailMirror.getValue(rd, fieldName);
						String masterColumnVal = getMasterColumnVal(rd, rt.getMasterColumn());
						indicatorValMap.put(masterColumnVal, indicatorValue);
					}

					map.put(indicatorId.toString(), indicatorValMap);
				}

			}
		}
		return map;
	}

	private List<Integer> getNumbericIndicator(String reportTypeId) {
		String sql = "SELECT  t.id  FROM  T_INDICATOR T "
				+ "INNER JOIN T_REPORT_TYPE_INDICATOR rti ON T.ID = RTI.INDICATOR_ID "
				+ "AND RTI.REPORT_TYPE_ID = @reportTypeId  WHERE  	T.data_type = '1'";
		Map<String, Object> params = ImmutableMap.<String, Object> of("reportTypeId", reportTypeId);
		return sqlTemplate.queryForList(sql, null, params, Integer.class);
	}

	private String getMasterColumnVal(ReportDetail rd, String masterColumnStr) {
		String[] masterColumns = masterColumnStr.split(",");
		List<String> mvVals = Lists.newArrayListWithCapacity(masterColumns.length);
		for (String mc : masterColumns) {
			int mcIndex = Integer.parseInt(mc) + 1;
			String fieldName = "f" + mcIndex;
			String mcVal = (String) reportDetailMirror.getValue(rd, fieldName);
			mvVals.add(mcVal);
		}
		return StringUtils.join(mvVals, "-");
	}

	public Map getReportAccounting(User user, ReportType reportType, String timeDate, int quarter) {
		String monthVlaue = "";
		final Map resultList = new HashMap();
		// 填报人的身份
		Role role = user.getUserUnit().getRole();
		// 填报人的单位
		Unit userUnit = user.getUserUnit();
		Area area = user.getUserUnit().getArea();
		String parentId = area.getParentId();
		// 海洋局用户
		if (ReportConstant.OCEAN.equals(role.getId())) {
			Integer summarizationType = reportType.getDataSummarization();
			// 不用汇总
			if (summarizationType == null || summarizationType.intValue() != 1) {
				return resultList;
			}
			HashMap param = new HashMap();

			//本级涉海厅局单位
			String sql = "select * from tbl_unit where UNIT_ROLE_ID='" + ReportConstant.SHEHAI_BUMEN
					+ "' and id in(select cid from TBL_UNIT_RELATION where pid=@unitId and DEPTH="
					+ ReportConstant.INTEGER_TYPE + ")";
			param.put("unitId", user.getUserUnit().getId());
			List<UnitNz> departList = sqlTemplate.query(sql, param, indicatorSystemDao.getEntity(UnitNz.class));
			List<Unit> departListNew = new ArrayList<Unit>();
			for (UnitNz depart : departList) {
				Unit unit = new Unit();
				unit.setId(depart.getId());
				departListNew.add(unit);
			}
			// 河北省海洋局
			Filter unitfilter = new Filter();
			unitfilter.addRule(new FilterRule(FilterConstant.EQUAL, "role.id", ReportConstant.OCEAN));
			unitfilter.addRule(new FilterRule(FilterConstant.EQUAL, "area.id", ReportConstant.PROVINCE_AREA_ID));
			List<Unit> unitList = unitDAO.find(Unit.class, unitfilter, null);
			final Unit unit = unitList.get(0);

			// 频率
			final String timeType = reportType.getTypeTime();
			// 年报类别
			final String yearType = reportType.getTypeYearTime();
			final String yearValue = timeDate.substring(0, 4);
			monthVlaue = timeDate.substring(5, 7);
			final int month = Integer.valueOf(monthVlaue);

			Cnd cnd = Cnd.where("reportTypeId", "=", reportType.getId());
			List<ReportTypeIndicator> indicatorRel = indicatorSystemDao.query(ReportTypeIndicator.class, cnd);

			// final CountDownLatch doneSignal = new CountDownLatch(query.size());
			// int threadCount = (int) (Runtime.getRuntime().availableProcessors() / (1 - 0.9));
			// ExecutorService es = Executors.newFixedThreadPool(threadCount);

			// 下级海洋行政管理部门数据
			List<ReportDetailNz> subUnitDetails = getReportDetails(ReportConstant.OCEAN, user.getUserUnit().getId(),
					yearValue, yearType, month, quarter, timeType, reportType.getId(),
					Short.valueOf(ReportConstant.FLAG_PROVINCE_PASSED_COMMITTED), unit.getId(),
					ReportConstant.INTEGER_TYPE);
			// 下级涉海部门数据
			List<ReportDetailNz> subDepartDetails = getReportDetails(ReportConstant.SHEHAI_BUMEN, user.getUserUnit()
					.getId(), yearValue, yearType, month, quarter, timeType, reportType.getId(),
					Short.valueOf(ReportConstant.FLAG_PROVINCE_PASSED_COMMITTED), unit.getId(),
					ReportConstant.LONG_TYPE);
			// 本级涉海部门数据
			Map<String, List<ReportDetailNz>> departDetails = getDepartReportDetail(departListNew, yearValue, yearType,
					month, quarter, timeType, reportType.getId(),
					Short.valueOf(ReportConstant.FLAG_PROVINCE_PASSED_COMMITTED), unit.getId());

			for (final ReportTypeIndicator rti : indicatorRel) {
				Map<String, String> indicatorValSum = getSumIndicatorValue(subUnitDetails, subDepartDetails,
						departListNew, departDetails, rti);
				resultList.put(rti.getIndicatorId(), indicatorValSum);
			}

		}

		return resultList;
	}

	/**
	 * 获得下级单位填报的报表详情.
	 * 
	 * @param userRoleId
	 * @param userAreaId
	 * @param reportYear
	 * @param reportYearTime
	 * @param month
	 * @param quarter
	 * @param timeType
	 * @param reportTypeId
	 * @param checkStatus
	 * @param provinceUnitId
	 * @param rti
	 * @return
	 */
	public List<ReportDetailNz> getReportDetails(String userRoleId, String unitId, String reportYear,
			String reportYearTime, Integer month, Integer quarter, String timeType, String reportTypeId,
			Short checkStatus, String provinceUnitId, byte depth) {
		String sql = "SELECT rd.* FROM "
				+ " tbl_report r INNER JOIN tbl_report_detail rd ON r.id = rd.report_id "
				//暂时去掉省级终审通过的条件
				//				+ " INNER JOIN tbl_report_unit ru ON ru.report_id = r.id AND ru.operator_unit = @provinceUnitId AND ru.check_status = @checkStatus "
				+ " INNER JOIN tbl_user u ON r.report_user_id = u.id "
				+ " INNER JOIN tbl_unit unit ON u.user_unit = unit.id "
				+ " WHERE "
				+ " u.user_role_id = @userRoleId and unit.id in(select cid from TBL_UNIT_RELATION where pid=@unitId and DEPTH=@depth) AND r.report_check_status = @checkStatus "
				+ " AND r.report_type_id = @reportTypeId  ";
		Map<String, Object> param = Maps.newHashMap();
		// 当前时间
		Calendar date = Calendar.getInstance();
		int monthValue = date.get(Calendar.MONTH);
		if (Integer.valueOf(timeType) == Constants.REPORT_TIME_MONTH) {
			sql += " AND r.report_timetype = @reportTimetype AND r.report_year = @reportYear AND r.month = @month ";
			param.put("month", month);

		} else if (Integer.valueOf(timeType) == Constants.REPORT_TIME_YEAR) {
			// 全年报时，获取去年的上报记录
			if (reportYearTime.equals("2")) {

				reportYearTime = "2";

			} else if (reportYearTime.equals("1")) { // 半年报
				// 获取去年的上报记录
				if (monthValue < 6) {
					reportYearTime = "2";
					reportYear = String.valueOf(Integer.valueOf(reportYear) - 1);
				}
				// 查今年半年
				else {
					// 首先获取当前年的第一次上报记录
					reportYearTime = "1";
				}
			}
			sql += " AND r.report_timetype = @reportTimetype AND r.report_year = @reportYear AND r.report_year_time = @reportYearTime ";
			param.put("reportYearTime", reportYearTime);

		} else {
			sql += " AND r.report_timetype = @reportTimetype AND r.report_year = @reportYear AND r.quarter = @quarter ";
			param.put("quarter", quarter);
		}
		param.put("provinceUnitId", provinceUnitId);
		param.put("reportTypeId", reportTypeId);
		param.put("reportTimetype", timeType + "");
		param.put("reportYear", reportYear);
		param.put("checkStatus", checkStatus);
		param.put("userRoleId", userRoleId);
		param.put("unitId", unitId);
		param.put("depth", depth);
		List<ReportDetailNz> result = sqlTemplate.query(sql, param, indicatorSystemDao.getEntity(ReportDetailNz.class));

		return result;
	}

	/**
	 * 同级涉海部门报表详情
	 * 
	 * @param unitId
	 * @param reportYear
	 * @param reportYearTime
	 * @param month
	 * @param quarter
	 * @param timeType
	 * @param reportTypeId
	 * @param checkStatus
	 * @param provinceUnitId
	 * @param rti
	 * @return
	 */
	public Map<String, List<ReportDetailNz>> getDepartReportDetail(List<Unit> departList, String reportYear,
			String reportYearTime, Integer month, Integer quarter, String timeType, String reportTypeId,
			Short checkStatus, String provinceUnitId) {
		String sql = "SELECT rd.* FROM "
				+ " tbl_report r INNER JOIN tbl_report_detail rd ON r.id = rd.report_id "
				//暂时去掉省级终审通过的条件
				//				+ " INNER JOIN tbl_report_unit ru ON ru.report_id = r.id AND ru.operator_unit = @provinceUnitId AND ru.check_status = @checkStatus "
				+ " INNER JOIN tbl_user u ON r.report_user_id = u.id "
				+ " INNER JOIN tbl_unit unit ON u.user_unit = unit.id "
				+ " WHERE u.user_unit = @unitId AND r.report_check_status = @checkStatus "
				+ " AND r.report_type_id = @reportTypeId  ";
		Map<String, Object> param = Maps.newHashMap();
		// 当前时间
		Calendar date = Calendar.getInstance();
		int monthValue = date.get(Calendar.MONTH);
		if (Integer.valueOf(timeType) == Constants.REPORT_TIME_MONTH) {
			sql += " AND r.report_timetype = @reportTimetype AND r.report_year = @reportYear AND r.month = @month ";
			param.put("month", month);

		} else if (Integer.valueOf(timeType) == Constants.REPORT_TIME_YEAR) {
			// 全年报
			if (reportYearTime.equals("2")) {

				reportYearTime = "2";

			} else if (reportYearTime.equals("1")) { // 半年报
				// 获取去年的上报记录
				if (monthValue < 6) {
					reportYearTime = "2";
					reportYear = String.valueOf(Integer.valueOf(reportYear) - 1);
				}
				// 查今年半年
				else {
					// 首先获取当前年的第一次上报记录
					reportYearTime = "1";
				}
			}
			sql += " AND r.report_timetype = @reportTimetype AND r.report_year = @reportYear AND r.report_year_time = @reportYearTime ";
			param.put("reportYearTime", reportYearTime);

		} else {
			sql += " AND r.report_timetype = @reportTimetype AND r.report_year = @reportYear AND r.quarter = @quarter ";
			param.put("quarter", quarter);
		}
		param.put("provinceUnitId", provinceUnitId);
		param.put("reportTypeId", reportTypeId);
		param.put("reportTimetype", timeType + "");
		param.put("reportYear", reportYear);
		param.put("checkStatus", checkStatus);

		Map<String, List<ReportDetailNz>> result = Maps.newHashMap();
		for (Unit unit : departList) {
			param.put("unitId", unit.getId());
			List<ReportDetailNz> details = sqlTemplate.query(sql, param,
					indicatorSystemDao.getEntity(ReportDetailNz.class));
			result.put(unit.getId(), details);
		}
		return result;
	}

	/**
	 * 根据指标关系对指标值进行汇总
	 * 
	 * @param subUnitDetails 下级海洋行政部门报表详情
	 * @param subDepartDetails 下级涉海部门报表详情
	 * @param departs 本级涉海部门
	 * @param departDetails 本级涉海部门报表详情
	 * @param rti 报表指标关系
	 * @return
	 */
	private Map<String, String> getSumIndicatorValue(List<ReportDetailNz> subUnitDetails,
			List<ReportDetailNz> subDepartDetails, List<Unit> departs, Map<String, List<ReportDetailNz>> departDetails,
			ReportTypeIndicator rti) {
		Map<String, String> result = Maps.newHashMap();

		Double subUnitSum = sumIndicatorValue(subUnitDetails, rti);
		if (subUnitSum > 0) {
			result.put("下级海洋局汇总", df.format(subUnitSum));
		}

		Double subDepartSum = sumIndicatorValue(subDepartDetails, rti);
		if (subDepartSum > 0) {
			result.put("下级涉海部门汇总", df.format(subDepartSum));
		}

		for (Unit depart : departs) {
			Double departSum = sumIndicatorValue(departDetails.get(depart.getId()), rti);
			if (departSum > 0) {
				result.put(depart.getUnitName(), df.format(departSum));
			}
		}
		return result;
	}

	/**
	 * 根据指标关系对报表进行求和汇总
	 * 
	 * @param details
	 * @param rti
	 * @return
	 */
	private Double sumIndicatorValue(List<ReportDetailNz> details, ReportTypeIndicator rti) {
		Double sum = 0d;
		for (ReportDetailNz detail : details) {
			if (detail.getRowIndex() == rti.getRow()) {
				String fieldName = String.format("f%d", (rti.getTheColumn()));
				String strIndicatorVal = (String) reportDetaiNzMirror.getValue(detail, fieldName);
				try {
					Double indicatorVal = Double.valueOf(strIndicatorVal);
					sum += indicatorVal;
				} catch (Exception e) {

				}
			}
		}
		return new BigDecimal(sum).setScale(10, BigDecimal.ROUND_HALF_UP).doubleValue();
	}

	public Result queryReportsDelete(String userAreaId, String userUnit, String reportSystem, String reportTypeId,
			String industryId, String reportVersion, Date startingReportDate, Date endingReportDate, Integer pageNum,
			Page page, String typeNo) {

		// 江苏省海洋局
		Filter unitfilter = new Filter();
		unitfilter.addRule(new FilterRule(FilterConstant.EQUAL, "role.id", ReportConstant.OCEAN));
		unitfilter.addRule(new FilterRule(FilterConstant.EQUAL, "area.id", ReportConstant.PROVINCE_AREA_ID));
		List<Unit> unitList = unitDAO.find(Unit.class, unitfilter, null);
		Unit unit = unitList.get(0);
		return reportDAOIpml.queryReportsDelete(unit.getId(), userAreaId, userUnit, reportSystem, reportTypeId,
				industryId, reportVersion, startingReportDate, endingReportDate, pageNum, page, typeNo);
	}

	public Result queryAllReport(String areaId, String unitName, String reportSystem, String reportTypeId,
			String industryId, String reportVersion, Date startingReportDate, Date endingReportDate, Integer pageNum,
			Page page, String status, String typeNo) {
		return reportDAOIpml.queryAllReport(areaId, unitName, reportSystem, reportTypeId, industryId, reportVersion,
				startingReportDate, endingReportDate, pageNum, page, status, typeNo);
	}

	public Map getLasttimeReportByTimetype(User user, ReportType reportType, String timeDate, String quarterDate) {
		Map result = null;
		if (reportType.getDataType().intValue() == Constants.ReportStyle.CELL.getValue()) {
			result = getLasttimeCellReport(user, reportType, timeDate, quarterDate);
		} else {
			result = getLasttimeRowReport(user, reportType, timeDate, quarterDate);
		}
		return result;
	}

	public Result queryReportTypes(Filter filter, Page page) {
		List<ReportType> reportTypes = reportTypeDAO.find(ReportType.class, filter, page);
		int count = reportTypeDAO.count(ReportType.class, filter);

		if (page == null) {
			return new Result(1, 1, count, reportTypes, new ArrayList<Event>());
		}
		return new Result(page.getPageNumber(), page.getPageSize(), count, reportTypes, new ArrayList<Event>());
	}

	// 获取报表版本的最大版本数值

	public String queryReportMaxVersion(Filter filter, Page page) {
		List<ReportVersion> versions = versionDAO.find(ReportVersion.class, filter, page);
		int count = versionDAO.count(ReportVersion.class, filter);
		if (count == 0) {
			return "v1.00.00";
		} else {
			return versions.get(0).getVersionNumber();
		}
	}

	// 获取报表版本的所有信息

	public Result queryReportVersion(Filter filter, Page page) {
		List<ReportVersion> versions = versionDAO.find(ReportVersion.class, filter, page);
		int count = versionDAO.count(ReportVersion.class, filter);
		if (page == null) {
			return new Result(1, 1, count, versions, new ArrayList<Event>());
		}
		return new Result(page.getPageNumber(), page.getPageSize(), count, versions, new ArrayList<Event>());
	}

	public String getShengId(String areaId) {
		String id = "";
		Area areaById = areaDAO.get(Area.class, areaId);
		if (!"0".equals(areaById.getParentId())) {
			id = getShengId(areaById.getParentId());
		} else {
			id = areaById.getId();
		}
		return id;
	}

	public Result queryReportsByParent(String reportProxyId, String userId, Short checkStatus, String reportSystem,
			String reportTypeCode, String reportVersion, Date startingReportDate, Date endingReportDate, String areaId,
			Integer pageNum, Page page, String typeNo) {
		return reportDAOIpml.queryReportsByParent(reportProxyId, userId, checkStatus, reportSystem, reportTypeCode,
				reportVersion, startingReportDate, endingReportDate, areaId, pageNum, page, typeNo);
	}

	public Result queryReportsByParentForWebUnit(String reportProxyId, String userId, Short checkStatus,
			String reportSystem, String reportTypeCode, String reportVersion, Date startingReportDate,
			Date endingReportDate, String areaId, Integer pageNum, Page page, String typeNo) {
		return reportDAOIpml.queryReportsByParentForWebUnit(reportProxyId, userId, checkStatus, reportSystem,
				reportTypeCode, reportVersion, startingReportDate, endingReportDate, areaId, pageNum, page, typeNo);
	}

	public Result queryReportsByProxy(String reportProxyId, String userId, Short checkStatus, String reportSystem,
			String reportTypeCode, String reportVersion, Date startingReportDate, Date endingReportDate, String areaId,
			Integer pageNum, Page page, String flag, String createYear, String tunitName) {
		return reportDAOIpml
				.queryReportsByProxy(reportProxyId, userId, checkStatus, reportSystem, reportTypeCode, reportVersion,
						startingReportDate, endingReportDate, areaId, pageNum, page, flag, createYear, tunitName);
	}

	public Result queryReportsHql(String hql, Page page, Object... paras) {
		// List<User> users = userDAO.find(User.class, filter, page);
		List<Report> findByHql = reportDAO.findByHql(hql, paras);
		List<Report> users = new ArrayList<Report>();
		if (page == null) {
			users = reportDAO.findEntitiesByHql(hql, 0, 20, paras);
			return new Result(1, 1, findByHql.size(), users, new ArrayList<Event>());
		} else {
			users = reportDAO.findEntitiesByHql(hql, page.getFirstResult(), page.getPageSize(), paras);
		}
		return new Result(page.getPageNumber(), page.getPageSize(), findByHql.size(), users, new ArrayList<Event>());
	}

	// 根据报表制度获取当前报表版本信息

	public ReportVersion getVersion(Filter filter, Page page) {
		List<ReportVersion> versions = versionDAO.find(ReportVersion.class, filter, page);
		int count = versionDAO.count(ReportVersion.class, filter);
		if (count > 0) {
			return versions.get(0);
		} else {
			return null;
		}
	}

	public ReportType queryReportTypeByTypeCode(String typeCode) {
		List<ReportType> reportTypes = new ArrayList<ReportType>();
		if (StringUtils.isNotBlank(typeCode)) {
			Filter filter = new Filter();
			filter.addRule(new FilterRule(FilterConstant.EQUAL, "id", typeCode));
			reportTypes = reportTypeDAO.find(ReportType.class, filter, null);
		}
		return reportTypes.get(0);
	}

	public List<ReportType> queryReportTypeByIndustryId(String industryId) {
		List<ReportType> reportTypes = new ArrayList<ReportType>();
		if (StringUtils.isNotBlank(industryId)) {
			String hql = "from ReportType as rt where exists(select id from DustryReport dr where dr.industry.id=:industryId and dr.reportTypeId=rt.id) order by rt.statSystem,rt.sortNo,rt.subSortNo";
			HashMap map = new HashMap();
			map.put("industryId", industryId);
			Result hqlParam = reportTypeDAO.hqlParam(hql, map, null);
			reportTypes = (List<ReportType>) hqlParam.getOperationResult();
		}
		return reportTypes;
	}

	public void removeReportTypes(String[] ids) {
		if (ids != null && ids.length > 0) {
			Filter filter = new Filter();
			filter.addRule(new FilterRule(FilterConstant.COLLECTION, "id", ids));

			List<ReportType> reportTypes = reportTypeDAO.find(ReportType.class, filter, null);

			for (ReportType reportType : reportTypes) {
				Filter filterRT = new Filter();
				filterRT.addRule(new FilterRule(FilterConstant.EQUAL, "reportTypeId", reportType.getId()));
				List<DustryReport> dustryReports = dustryReportDAO.find(DustryReport.class, filterRT, null);
				dustryReportDAO.delete(dustryReports);
			}

			reportTypeDAO.delete(reportTypes);
		}
	}

	private ReportType checkReportTypeName(String name) {
		Filter filter = new Filter();
		filter.addRule(new FilterRule(FilterConstant.EQUAL, "typeName", name));

		List<ReportType> reportTypes = reportTypeDAO.find(ReportType.class, filter, null);
		if (reportTypes.size() > 0) {
			return reportTypes.get(0);
		}
		return null;
	}

	public Report toPersistReport(cn.com.generaldata.os.pojo.mvc.Report mvcReport) {
		User user = new User();
		user.setId(mvcReport.getReportUserId());

		User operator = new User();
		operator.setId(mvcReport.getReportOperatorId());

		Area area = new Area();
		area.setId(mvcReport.getReportAreaId());

		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
		// if(mvcReport.getReportDate()==null)
		// mvcReport.setReportDate();
		Integer quarter = null;
		if (mvcReport.getReportQuarter() != null && !"".equals(mvcReport.getReportQuarter())) {
			quarter = new Integer(1);
			if ("第一季度".equals(mvcReport.getReportQuarter())) {
				quarter = 1;
			} else if ("第二季度".equals(mvcReport.getReportQuarter())) {
				quarter = 2;
			} else if ("第三季度".equals(mvcReport.getReportQuarter())) {
				quarter = 3;
			} else if ("第四季度".equals(mvcReport.getReportQuarter())) {
				quarter = 4;
			}
		}
		Calendar date = Calendar.getInstance();
		int monthValue = date.get(Calendar.MONTH);
		int year = date.get(Calendar.YEAR);
		String month = mvcReport.getReportMonth();
		Integer mon = null;
		if (month != null && !"".equals(month)) {
			mon = new Integer(1);
			String[] split = month.split("/");
			String a = split[1];
			mon = Integer.valueOf(a);
		} else {
			if (monthValue < 9)
				month = year + "/0" + (monthValue + 1);
			else
				month = year + "/" + (monthValue + 1);
		}
		try {
			return new Report(mvcReport.getReportId(), mvcReport.getReportReferenceId(), user, operator, area,
					mvcReport.getReportType(), mvcReport.getReportTypeCode(), mvcReport.getReportType(),
					mvcReport.getRegionName(), mvcReport.getRegionOcean(), mvcReport.getCityName(),
					mvcReport.getDepartmentName(), mvcReport.getRegionCode(), mvcReport.getReportUnit(),
					mvcReport.getReportUnitIndustry(), mvcReport.getReportUnitIndustryId(),
					mvcReport.getInstitutionName(), mvcReport.getInstitutionCode(), mvcReport.getDomainName(),
					mvcReport.getDomainCode(), mvcReport.getReportYear(), mvcReport.getReportQuarter(),
					mvcReport.getReportNo(), mvcReport.getReportAdmin(), mvcReport.getApproveAdmin(),
					mvcReport.getApproveNo(), mvcReport.getExpireDate(), mvcReport.getMeasureUnit(),
					mvcReport.getUnitAdmin(), mvcReport.getStatAdmin(), mvcReport.getFillAdmin(),
					formatter.parse(mvcReport.getReportDate() == "" || mvcReport.getReportDate() == null ? formatter
							.format(new Date()) : mvcReport.getReportDate()), mvcReport.getReportOrigin(),
					mvcReport.getReportSupplyOrigin(), mvcReport.getReportDesc(), mvcReport.getCreateDate(),
					mvcReport.getLastEditDate(), Byte.valueOf(mvcReport.getCheckStatus()), mvcReport.getCheckComment(),
					mvcReport.getCheckResult(), mvcReport.getCheckSuccessDate(), mvcReport.getReportRemark(),
					mvcReport.getReportFlag(), mvcReport.getReportProxyId(), null, mvcReport.getReportTimetype(),
					month, mvcReport.getReportYearTime(), mvcReport.getReportVersion(), mvcReport.getReportTypeId(),
					mvcReport.getReportEdition(), quarter, mon, mvcReport.getUnitId(), mvcReport.getUpdateTime());
		} catch (NumberFormatException e) {
			e.printStackTrace();
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return null;
	}

	public Set<ReportDetail> toPersistReportDetail(cn.com.generaldata.os.pojo.mvc.Report mvcReport) {
		Set<ReportDetail> reportDetails = new HashSet<ReportDetail>();

		for (Row row : mvcReport.getRows()) {
			Report report = new Report();
			if (StringUtils.isNotBlank(mvcReport.getReportId())) {
				report.setId(mvcReport.getReportId());
			}

			ReportDetail reportDetail = new ReportDetail(row.getRowId(), report, row.getRowType(), row.getGroupNo(),
					row.getRowIndex(), row.getF1(), row.getF2(), row.getF3(), row.getF4(), row.getF5(), row.getF6(),
					row.getF7(), row.getF8(), row.getF9(), row.getF10(), row.getF11(), row.getF12(), row.getF13(),
					row.getF14(), row.getF15(), row.getCreateDate(), row.getLastEditDate(), row.getF16(), row.getF17(),
					row.getF18(), row.getF19(), row.getF20(), row.getF21(), row.getF22(), row.getF23(), row.getF24(),
					row.getF25(), row.getF26(), row.getF27(), row.getF28(), row.getF29(), row.getF30(), row.getF31(),
					row.getF32(), row.getF33(), row.getF34(), row.getF35(), row.getF36(), row.getF37(), row.getF38(),
					row.getF39(), row.getF40(), row.getF41(), row.getF42(), row.getF43(), row.getF44(), row.getF45(),
					row.getF46(), row.getF47(), row.getF48(), row.getF49(), row.getF50(), row.getF51(), row.getF52(),
					row.getF53(), row.getF54(), row.getF55(), row.getF56(), row.getF57(), row.getF58(), row.getF59(),
					row.getF60());

			reportDetails.add(reportDetail);
		}
		return reportDetails;
	}

	private cn.com.generaldata.os.pojo.mvc.Report toMVCReport(Report report, List<ReportDetail> reportDetails) {
		ReportType rType = new ReportType();
		rType = this.queryReportTypeByTypeCode(report.getReportTypeId());
		List<Row> rows = new ArrayList<Row>();
		for (ReportDetail reportDetail : reportDetails) {
			Row row = BeanMapper.map(reportDetail, Row.class);
			row.setRowId(reportDetail.getId());
			rows.add(row);
		}

		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");

		return new cn.com.generaldata.os.pojo.mvc.Report(String.valueOf(report.getId()), String.valueOf(report
				.getReportReferenceId()), report.getReportType(), report.getReportTypeCode(), String.valueOf(report
				.getUser().getId()), report.getReportRegionName(), report.getReportRegionOcean(),
				report.getReportCityName(), report.getReportDepartmentName(), report.getReportRegionCode(),
				report.getReportUnit(), report.getReportUnitIndustry(), report.getReportUnitIndustryId(),
				report.getReportInstitutionName(), report.getReportInstitutionCode(), report.getReportDomainName(),
				report.getReportDomainCode(), report.getReportYear(), report.getReportQuarter(), rType.getTypeNo(),
				rType.getTypeReportAdmin().toString(), rType.getTypeApproveAdmin().toString(),
				rType.getTypeApproveNo(), rType.getTypeExpireDate(), rType.getTypeMeasureUnit(),
				report.getReportUnitAdmin(), report.getReportStatAdmin(), report.getReportFillAdmin(),
				formatter.format(report.getReportDate()), report.getReportOrigin(), report.getReportSupplyOrigin(),
				report.getReportDesc(), report.getReportCreateTime(), report.getReportLastEditTime(),
				String.valueOf(report.getOperator().getId()), String.valueOf(report.getArea().getId()),
				Byte.valueOf(String.valueOf(report.getReportCheckStatus())), report.getReportCheckComment(),
				report.getReportCheckResult(), report.getReportCheckSuccessDate(), report.getReportRemark(),
				report.getReportFlag(), report.getReportProxyId(), rows, report.getReportTimetype(),
				report.getReportMonth(), report.getReportYearTime(), report.getReportVersion(),
				report.getReportTypeId(), report.getReportEdition(), report.getSelfSet1(), report.getSelfSet2(),
				report.getSelfSet3(), report.getSelfSet4(), report.getSelfSet5(), report.getQuarter(),
				report.getMonth(), report.getUnitId(), report.getUpdateTime());
	}

	@SuppressWarnings("unchecked")
	private void markReport(String reportId, byte status) {
		Report report = queryReportById(reportId);

		Filter filter = new Filter();
		filter.setOrder(FilterConstant.ASC);
		filter.setSortBy("rowIndex");
		filter.addRule(new FilterRule(FilterConstant.EQUAL, "report.id", reportId));
		List<ReportDetail> reportDetails = (List<ReportDetail>) queryReportDetails(filter, null).getOperationResult();

		if (report != null) {
			switch (status) {
			case ReportConstant.FLAG_COMMITTED:
				markingService.mark4Submitting(toMVCReport(report, reportDetails));
				break;
			case ReportConstant.FLAG_PROVINCE_PASSED_UNCOMMITTED:
				markingService.mark4Submitting(toMVCReport(report, reportDetails));
				break;
			case ReportConstant.FLAG_PASSED:
				markingService.mark4Passing(toMVCReport(report, reportDetails));
				break;
			case ReportConstant.FLAG_PROVINCE_PASSED_COMMITTED:
				markingService.mark4Passing(toMVCReport(report, reportDetails));
				break;
			case ReportConstant.FLAG_REJECTED:
				markingService.mark4Rejecting(toMVCReport(report, reportDetails));
				break;
			case ReportConstant.FLAG_PROVINCE_REJECTED:
				markingService.mark4Rejecting(toMVCReport(report, reportDetails));
				break;
			default:
			}
		}
	}

	public void import_report(User user, String reportProxyId, cn.com.generaldata.os.newpojo.ReportType rType,
			String timeType, String yearType, String timeDate, String unitIndustryId, String reportVersion,
			String quarterDate, File file, ReportExcelSectionVO sectionInfo) throws Exception {
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
		Workbook wb = null;

		// int rowNum = 0;
		try {
			wb = WorkbookFactory.create(file);
			Sheet sheet = wb.getSheetAt(0);
			if (sheet != null) {

				Date date = new Date();
				User opera = new User();
				opera.setId(reportProxyId);
				Industry industry = industryDAO.get(Industry.class, unitIndustryId);
				String yearValue = "";
				String monthValue = "";
				String quarterValue = "";
				// 获取当前时间的年份
				if (timeType.equals("1")) {
					yearValue = timeDate.substring(0, 4);
					monthValue = timeDate;
				}
				if (timeType.equals("0")) {
					monthValue = timeDate;
				}
				if (timeType.equals("2")) {
					yearValue = timeDate.substring(0, 4);
					quarterValue = quarterDate;
				}
				Integer quarter = null;
				if (quarterValue != null && !"".equals(quarterValue)) {
					quarter = new Integer(1);
					if ("第一季度".equals(quarterValue)) {
						quarter = 1;
					} else if ("第二季度".equals(quarterValue)) {
						quarter = 2;
					} else if ("第三季度".equals(quarterValue)) {
						quarter = 3;
					} else if ("第四季度".equals(quarterValue)) {
						quarter = 4;
					}
				}
				String month = monthValue;
				Integer mon = null;
				if (month != null && !"".equals(month)) {
					mon = new Integer(1);
					String[] split = month.split("/");
					String a = split[1];
					mon = Integer.valueOf(a);
				}
				System.out.println("*****导入的用户ID:" + user.getId());
				System.out.println("*****导入的地区ID:" + user.getArea().getId());
				Report report = new Report(null, null, user, opera, user.getArea(), rType.getTypeName(), "",
						rType.getTypeName(), null, null, null, null, null, user.getUserUnit().getUnitName(),
						industry == null ? "" : industry.getDustryName(), unitIndustryId, null, null, null, null,
						yearValue, quarterValue, "", "", "", "", "", "", "", "", "", date, null, null, null, date,
						date, Short.valueOf("0"), "", null, null, "", "0", reportProxyId, null, timeType, month,
						yearType, "v1.00.00", rType.getId(), "", quarter, mon, user.getUserUnit().getId(), null);
				// 当时年报时，获取年报的次数
				if (timeType.equals("1")) {
					int year = date.getYear();
					int monthNow = date.getMonth();
					if (yearType.equals("1")) { // 半年
						// 若今年的就是半年报
						if (monthNow < 6) {
							report.setReportYearTime("2");
							report.setReportYear(String.valueOf(Integer.valueOf(yearValue) - 1));
						} else {
							report.setReportYearTime("1");
						}

					} else if (yearType.equals("2")) { // 全年报

						report.setReportYearTime("2");

					}
				}
				List<ReportExcelInputInfo> infos = sectionInfo.getInputInfos();
				Mirror<Report> mirrorReport = Mirror.me(Report.class);
				for (ReportExcelInputInfo info : infos) {
					int rowIndex = info.getRowIndex();
					int columnIndex = info.getColumnIndex();
					Cell cell = sheet.getRow(rowIndex).getCell(columnIndex);
					if (cell != null) {
						int cellType = cell.getCellType();
						String value = "";
						if (cellType == 0) {
							Integer cellValue = (int) cell.getNumericCellValue();
							Calendar dateNow = Calendar.getInstance();
							dateNow.set(Calendar.YEAR, 1900);
							dateNow.set(Calendar.MONTH, 0);
							dateNow.set(Calendar.DAY_OF_YEAR, cellValue - 1);
							value = dateNow.get(Calendar.YEAR) + "-" + (dateNow.get(Calendar.MONTH) + 1) + "-"
									+ dateNow.get(Calendar.DAY_OF_MONTH);
							// System.out.println(dateNow.get(Calendar.MONTH)+1);
							// System.out.println(dateNow.get(Calendar.DAY_OF_MONTH));
						} else {
							value = cell.getStringCellValue();
						}
						Field field = Report.class.getDeclaredField(info.getAttrName());

						String type = field.getGenericType().toString();
						if (type.equals("class java.util.Date")) {

							Date dateValue = new Date();
							value = value.replaceAll(" ", "").replaceAll("/", "-").replaceAll("\\.", "-")
									.replaceAll("年", "-").replaceAll("月", "-").replaceAll("日", "");
							if (StringUtils.isNotBlank(value))
								dateValue = sf.parse(value);

							mirrorReport.setValue(report, info.getAttrName(), dateValue);
						} else {
							mirrorReport.setValue(report, info.getAttrName(), value);
						}
					}
				}
				if (report.getId() == null || "".equals(report.getId()))
					report.setId(UUID.randomUUID().toString().replaceAll("-", ""));

				reportDAO.save(report);

				Mirror<ReportDetail> mirror = Mirror.me(ReportDetail.class);
				int tableBodyStartRow = sectionInfo.getTableBodyStartRow();
				int tableBodyEndRow = sectionInfo.getTableBodyEndRow();
				int j = 0;
				for (int i = tableBodyStartRow; i <= tableBodyEndRow; i++) {
					org.apache.poi.ss.usermodel.Row row = sheet.getRow(i);
					ReportDetail reportDetail = new ReportDetail();
					reportDetail.setReport(report);
					reportDetail.setCreateTime(date);
					reportDetail.setLastEditTime(date);
					reportDetail.setRowIndex(j);
					reportDetail.setRowType(11);
					j++;
					for (int cellIndex = 0, maxCellIndex = 60; cellIndex < maxCellIndex; cellIndex++) {
						Cell cell = row.getCell(cellIndex);
						if (cell != null) {
							String cellVal = Castors.me().castTo(Excels.getCellValue(cell), String.class);

							// 注意科学计数法
							if (pattern.matcher(cellVal).matches()) {
								BigDecimal db = new BigDecimal(cellVal);
								cellVal = db.toPlainString();
							}
							String fieldName = "f" + (cell.getColumnIndex() + 1);
							mirror.setValue(reportDetail, fieldName, cellVal);
						}
					}
					if (reportDetail.getId() == null || "".equals(reportDetail.getId()))
						reportDetail.setId(UUID.randomUUID().toString().replaceAll("-", ""));

					reportDetailDAO.save(reportDetail);
				}
			}
		} catch (InvalidFormatException e) {
			log.error("Excel单元格格式错误", e);
		} catch (IOException e) {
			log.error("Excel文件错误", e);
		}
		file.delete();
	}

	public String[] getSubAreaIds(String parentAreaId) {
		Filter filter = new Filter();
		filter.addRule(new FilterRule(FilterConstant.EQUAL, "parentId", parentAreaId));

		List<Area> areas = areaDAO.find(Area.class, filter, null);
		String[] areaIds = new String[areas.size()];
		for (int i = 0; i < areas.size(); i++) {
			areaIds[i] = areas.get(i).getId();
		}
		if (areaIds.length > 0) {
			return areaIds;
		}
		return null;
	}

	/**
	 * 绩效评估
	 * 
	 * @param unitId
	 * @param timeType
	 */

	public cn.com.generaldata.os.vo.ReportPerformVO reportAccount(String id, String timeDate, String type) {

		cn.com.generaldata.os.vo.ReportPerformVO result = new cn.com.generaldata.os.vo.ReportPerformVO();

		List<Unit> unitList = new ArrayList<Unit>();
		Unit unit = unitDAO.get(Unit.class, id);
		// List<ReportPerform> pplist = new ArrayList<ReportPerform>();

		String unitId = unit.getId();
		result.setUnitId(unitId);
		result.setUnitName(unit.getUnitName());
		List<ReportVersion> versionList = versionDAO.find(ReportVersion.class, null, null);
		int sum = 0;
		// 已上报的总数
		int reported = 0;
		// 被催报的总数
		int billNum = 0;
		// 被驳回的总数
		int rejectNum = 0;
		int yearSelect = 1990;
		int monthSelect = 99;
		if (timeDate != null && !"".equals(timeDate)) {
			yearSelect = Integer.valueOf(timeDate.substring(0, 4));
			String substring = timeDate.substring(5);
			if ("- -".equals(substring.trim())) {
				monthSelect = 99;
			} else {
				monthSelect = Integer.valueOf(substring);
			}
		}

		Filter filter = new Filter();
		filter.addRule(new FilterRule(FilterConstant.EQUAL, "userUnit.id", unitId));
		// 该单位的所有用户
		List<User> oceanUsers = userDAO.find(User.class, filter, null);
		List<User> users = new ArrayList<User>();
		if (oceanUsers != null && oceanUsers.size() > 0) {
			users.add(oceanUsers.get(0));
		}

		if (users != null && users.size() > 0) {

			// 每个单位的用户
			for (User user : users) {

				// 该单位所有行业ID
				List<String> uindustrys = new ArrayList<String>();

				Filter filterIndustry = new Filter();
				filterIndustry.addRule(new FilterRule(FilterConstant.EQUAL, "user.id", user.getId()));
				List<UserIndustry> userIndustrys = userIndustryDAO.find(UserIndustry.class, filterIndustry, null);
				if (userIndustrys != null && userIndustrys.size() > 0) {
					for (int i = 0; i < userIndustrys.size(); i++) {
						uindustrys.add(userIndustrys.get(i).getIndustry().getId());
					}
				}
				if (uindustrys.size() == 0) {
					uindustrys.add("");
				}
				Filter filter2 = new Filter();
				filter2.addRule(new FilterRule(FilterConstant.COLLECTION, "industry.id", uindustrys.toArray()));
				// 所有相关行业报表
				List<DustryReport> dReports = dustryReportDAO.find(DustryReport.class, filter2, null);
				if (dReports != null && dReports.size() > 0) {
					List<String> rids = new ArrayList<String>();
					for (DustryReport dr : dReports) {
						rids.add(dr.getReportTypeId());
					}
					if (rids.size() == 0) {
						rids.add("");
					}
					String hql = " from ReportType where id in(:ids) or statSystem=2";
					HashMap map = new HashMap();
					map.put("ids", rids.toArray());
					Result hqlParam = reportTypeDAO.hqlParam(hql, map, null);
					// 该单位需要报的报表
					List<ReportType> list = (List<ReportType>) hqlParam.getOperationResult();
					// 判断用户身份(企业用户、涉海部门要过滤)
					List<String> queryReportTypesUnit = queryReportTypesUnit(user.getUserUnit().getId());

					// 可以填报报表的总数
					if (list != null && list.size() > 0) {
						for (ReportType rt : list) {
							if (queryReportTypesUnit.size() > 0 && !queryReportTypesUnit.contains(rt.getId())) {
								continue;
							}
							for (int m = 1; m <= 12; m++) {
								if (monthSelect != 99 && m != monthSelect)
									continue;
								Calendar dateNow = Calendar.getInstance();
								Calendar dateCurr = Calendar.getInstance();

								dateNow.set(Calendar.YEAR, yearSelect);
								dateCurr.set(Calendar.YEAR, yearSelect);
								dateNow.set(Calendar.MONTH, m - 1);
								dateCurr.set(Calendar.MONTH, m - 1);
								int month = 0;
								int quarterNow = 1;
								int yearNow = dateNow.get(Calendar.YEAR);
								Date startYear = dateNow.getTime();
								Date endYear = dateNow.getTime();
								month = dateNow.get(Calendar.MONTH);
								for (ReportVersion version : versionList) {
									if (rt.getVersionId().intValue() == version.getId()) {
										startYear = version.getStartDate();
										endYear = version.getEndDate();
										break;
									}
								}
								int monthNow = dateNow.get(Calendar.MONTH) + 1;
								if (monthNow < 4) {
									quarterNow = 1;
								} else if (monthNow > 3 && monthNow < 7) {
									quarterNow = 2;
								} else if (monthNow > 6 && monthNow < 10) {
									quarterNow = 3;
								} else if (monthNow > 9) {
									quarterNow = 4;
								}
								// dateCurr.set(Calendar.DAY_OF_YEAR,
								// dateNow.get(Calendar.DAY_OF_YEAR)
								// - time_limit);
								// int day =
								// dateCurr.get(Calendar.DAY_OF_MONTH);
								Filter filteReject = new Filter();
								String typeYear = rt.getTypeYearTime();
								// 下半年报上半年的
								if ("1".equals(rt.getTypeYearTime())) {
									int monthValue = Calendar.getInstance().get(Calendar.MONTH);
									if (monthValue > 5)
										typeYear = "4";
								}
								// 测试，why改的
								List<ReportTypeLimit> limitList = queryReportLimit(rt.getStatSystem(), rt.getId(),
										rt.getTypeTime(), typeYear);
								// List<ReportTypeLimit> limitList = new
								// ArrayList<ReportTypeLimit>();

								for (ReportTypeLimit reportLimit : limitList) {
									Integer startDay = reportLimit.getStartDay();
									Integer endDay = reportLimit.getEndDay();
									Integer startMonth = reportLimit.getStartMonth();
									Integer endMonth = reportLimit.getEndMonth();
									month = dateCurr.get(Calendar.MONTH);
									int year = dateCurr.get(Calendar.YEAR);
									// 月报
									if ("0".equals(rt.getTypeTime())
											&& rt.getTypeTime().equals(reportLimit.getTypeTime())) {
										sum++;
										String dateTime = year + "/" + monthNow;
										if (monthNow < 10) {
											dateTime = year + "/0" + monthNow;
										}
										if (month == 0)
											dateTime = year - 1 + "/12";
										List<Report> reporteds = queryReportsByBillboardUser(rt.getId(),
												rt.getTypeTime(), rt.getTypeYearTime(), "", dateTime, "", user.getId());
										if (reporteds != null && reporteds.size() > 0) {
											reported++;
											Report report = reporteds.get(0);
											if (report.getReportCheckStatus() == 3) {
												rejectNum++;
											}
										}
										Integer queryBillByReport = queryBillByReport(rt.getId(), unitId,
												rt.getTypeTime(), rt.getTypeYearTime(), dateTime, "");
										if (queryBillByReport != null) {
											billNum++;
										}
										break;
									}
									// 季报
									else if ("2".equals(rt.getTypeTime())
											&& rt.getTypeTime().equals(reportLimit.getTypeTime())) {
										String quarterName = "";
										if (quarterNow == 1 && month == 3) {
											quarterName = "第一季度";
											sum++;
										} else if (quarterNow == 2 && month == 6) {
											quarterName = "第二季度";
											sum++;
										} else if (quarterNow == 3 && month == 9) {
											quarterName = "第三季度";
											sum++;
										} else if (quarterNow == 4 && month == 0) {
											quarterName = "第四季度";
											year--;
											sum++;
										}
										String dateTime = year + "/" + monthNow;
										if (monthNow < 10) {
											dateTime = year + "/0" + monthNow;
										}
										List<Report> reporteds = queryReportsByBillboardUser(rt.getId(),
												rt.getTypeTime(), rt.getTypeYearTime(), quarterName, dateTime, "",
												user.getId());
										if (reporteds != null && reporteds.size() > 0) {
											reported++;
											Report report = reporteds.get(0);
											if (report.getReportCheckStatus() == 3) {
												rejectNum++;
											}
										}
										Integer queryBillByReport = queryBillByReport(rt.getId(), unitId,
												rt.getTypeTime(), rt.getTypeYearTime(), dateTime, quarterName);
										if (queryBillByReport != null) {
											billNum++;
										}
										break;
									}
									// 年报
									else if ("1".equals(rt.getTypeTime())
											&& rt.getTypeTime().equals(reportLimit.getTypeTime())) {
										// 半年报
										if (("1".equals(typeYear) || "4".equals(typeYear))
												&& reportLimit.getTypeYearTime().equals(typeYear)) {
											if (monthNow == startMonth)
												sum++;
										}
										// 全年报
										else if ("2".equals(rt.getTypeYearTime())
												&& reportLimit.getTypeYearTime().equals(typeYear)) {
											if (monthNow >= startMonth && monthNow <= endMonth)
												sum++;
										}
										String dateTime = year + "/" + monthNow;
										if (monthNow < 10) {
											dateTime = year + "/0" + monthNow;
										}
										List<Report> reporteds = queryReportsByBillboardUser(rt.getId(),
												rt.getTypeTime(), rt.getTypeYearTime(), "", dateTime, "", user.getId());
										if (reporteds != null && reporteds.size() > 0) {
											reported++;
											Report report = reporteds.get(0);
											if (report.getReportCheckStatus() == 3) {
												rejectNum++;
											}
										}
										Integer queryBillByReport = queryBillByReport(rt.getId(), unitId,
												rt.getTypeTime(), rt.getTypeYearTime(), dateTime, "");
										if (queryBillByReport != null) {
											billNum++;
										}
										break;
									}
								}
							}
						}
					}
				}
			}
		}
		result.setSumNum(sum);
		result.setRejectNum(rejectNum);
		result.setBillNum(billNum);
		result.setReportedNum(reported);
		// System.out.println(perform.getId());
		// pplist.add(perform);

		return result;
	}

	public String buildExcel(String unitId) {

		Properties properties = new Properties();
		java.io.InputStream inputstream = getClass().getResourceAsStream("/fileupload.properties");
		try {
			properties.load(inputstream);
		} catch (Exception ex) {
			log.error("加载配置文件出错", ex);
		}
		File fileFolder = new File(properties.getProperty("excelTemplePath").trim());
		if (!fileFolder.exists() || !fileFolder.isDirectory())
			fileFolder.mkdir();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
		String folder = String.valueOf(sdf.format(new Date()));
		// String folder = String.valueOf(dirCount.getAndIncrement());

		List<String> typesUnit = queryReportTypesUnit(unitId);
		for (String reportId : typesUnit) {
			cn.com.generaldata.jsme_indicator_system.entity.ReportType reportType = indicatorSystemDao.fetch(
					cn.com.generaldata.jsme_indicator_system.entity.ReportType.class, reportId);
			String reportInfo = reportType.getReportInfo();
			cn.com.generaldata.jsme_indicator_system.vo.reportdesigner.Report report = Json.fromJson(
					cn.com.generaldata.jsme_indicator_system.vo.reportdesigner.Report.class, reportInfo);
			File file = reportExcelTemplateBuilder.buildReportExcelTemplate(report,
					properties.getProperty("excelTemplePath").trim() + folder, reportType.getTypeNo() + "-"
							+ reportType.getTypeName());
		}
		String zipPath = folder + ".zip";
		ZipCompressor zc = new ZipCompressor(properties.getProperty("excelTemplePath").trim() + zipPath);
		zc.compress(properties.getProperty("excelTemplePath").trim() + folder); // 压缩一个文件夹

		return zipPath;
	}

	public Map<String, String> queryStatSystem(String unitId) {
		List<String> typesUnit = queryReportTypesUnit(unitId);
		List<Integer> statIds = new ArrayList<Integer>();
		for (String reportId : typesUnit) {
			cn.com.generaldata.jsme_indicator_system.entity.ReportType reportType = indicatorSystemDao.fetch(
					cn.com.generaldata.jsme_indicator_system.entity.ReportType.class, reportId);
			Integer statSystem = reportType.getStatSystem();
			statIds.add(statSystem);
		}
		Map<String, String> re = Maps.newLinkedHashMap();

		if (statIds.size() > 0) {
			List<StatSystem> statSystems = indicatorSystemDao.query(StatSystem.class, Cnd.where("id", "in", statIds));

			for (StatSystem statSystem : statSystems) {
				re.put(statSystem.getId().toString(), statSystem.getName());
			}
		}
		return re;
	}

	public List<String> queryReportTypesUnit(String unitId) {
		List<String> typeList = new ArrayList<String>();
		Unit unit = unitDAO.get(Unit.class, unitId);
		if (unit != null) {
			Role role = unit.getRole();
			// 企业用户
			if ("3".equals(role.getId())) {
				String sql = "select * from t_report_type_unit_type where 1=1";
				if (unit.getUnitProper() != null) {
					if (unit.getUnitProper().contains("1") && unit.getUnitProper().contains("2"))
						sql += "and (report_unit_type=3 or report_unit_type=2)";
					//用海企业
					else if (unit.getUnitProper().contains("2"))
						sql += " and report_unit_type=2";
					//涉海企业
					else if (unit.getUnitProper().contains("1"))
						sql += " and report_unit_type=3";
				}
				List<ReportTypeUnitType> list = sqlTemplate.query(sql, null, ReportTypeUnitType.class);

				for (ReportTypeUnitType rt : list)
					typeList.add(rt.getReportTypeId());
			} else if ("5".equals(role.getId())) {
				Criteria cri = Cnd.cri();
				cri.where().and("unit_id", "=", unitId);
				List<ReportTypeUnit> list = indicatorSystemDao.query(ReportTypeUnit.class, cri);
				for (ReportTypeUnit rt : list)
					typeList.add(rt.getReportTypeId());
			}
		}
		return typeList;
	}

	public List<String> queryReportTypesUser(String userId) {
		//		List<String> typeList = new ArrayList<String>();
		//		Criteria cri = Cnd.cri();
		//		cri.where().and("userId", "=", userId);
		String sql = "select distinct trt.id from tbl_report_type trt where exists(select id from tbl_dustry_report tdr where tdr.REPORT_TYPE_ID=trt.id "
				+ " and exists(select id from tbl_user_industry tui where tui.INDUSTRY_ID=tdr.INDUSTRY_ID and tui.USER_ID=@userId)) "
				+ " and EXISTS(select id from tbl_report_version rv where rv.id=trt.version_id and rv.active=1)";
		Map<String, Object> param = Maps.newHashMap();
		param.put("userId", userId);
		List<String> typeList = sqlTemplate.queryForList(sql, null, param, String.class);
		//		List<UserIndustryNz> groupList = indicatorSystemDao.query(UserIndustryNz.class, cri);
		//		for (UserIndustryNz uiz : groupList) {
		//			Criteria cri2 = Cnd.cri();
		//			cri2.where().and("industryId", "=", uiz.getIndustryId());
		//			List<DustryReportNz> reportGroup = indicatorSystemDao.query(DustryReportNz.class, cri2);
		//			for (DustryReportNz nz : reportGroup)
		//				typeList.add(nz.getReportTypeId());
		//		}
		return typeList;
	}

	/**
	 * 报送提醒
	 * 
	 * @param unitId
	 * @param timeType
	 */

	public List<cn.com.generaldata.os.vo.ReportVO> reportAlert(String userid) {
		List<cn.com.generaldata.os.vo.ReportVO> result = new ArrayList<cn.com.generaldata.os.vo.ReportVO>();
		List<ReportVersion> versionList = versionDAO.find(ReportVersion.class, null, null);
		//		Filter filter = new Filter();
		User user2 = userDAO.get(User.class, userid);
		//		filter.addRule(new FilterRule(FilterConstant.EQUAL, "userUnit.id", user2.getUserUnit().getId()));
		// 该单位的所有用户
		//		List<User> users = userDAO.find(User.class, filter, null);
		//		if (users != null && users.size() > 0) {
		// 该单位所有行业ID

		String hql = "select rt.id,rt.stat_system,rt.version_id,rt.type_name,rt.type_no,rt.type_year_time,rt.type_time from tbl_report_type rt where 1=1";
		if (!StringUtils.isBlank(userid))
			hql += " and (exists(select id from TBL_DUSTRY_REPORT dr where dr.REPORT_TYPE_ID=rt.id and exists(select id from TBL_USER_INDUSTRY ui where ui.INDUSTRY_ID=dr.INDUSTRY_ID and ui.USER_ID=@userid)) or rt.stat_system=2) order by rt.stat_system,rt.sort_no,rt.sub_sort_no";
		//				String hql = "select id,statSystem,versionId,typeName,typeNo,typeYearTime,typeTime from ReportType where id in(:ids) or statSystem=2 order by statSystem,sortNo,subSortNo";
		HashMap map = new HashMap();
		map.put("userid", userid);
		//查询所有报表
		List<ReportTypeNz> list = sqlTemplate.query(hql, map, indicatorSystemDao.getEntity(ReportTypeNz.class));

		// 该单位需要报的报表
		//				List<ReportType> list = (List<ReportType>) hqlParam.getOperationResult();
		// 判断用户身份(企业用户、涉海部门要过滤)
		List<String> queryReportTypesUnit = queryReportTypesUnit(user2.getUserUnit().getId());

		// list.addAll(find);
		// 可以填报报表的总数
		if (list != null && list.size() > 0) {
			List<StatSystem> statSystems = indicatorSystemDao.query(StatSystem.class, Cnd.orderBy().asc("no"));

			for (ReportTypeNz rt : list) {
				if (queryReportTypesUnit.size() > 0 && !queryReportTypesUnit.contains(rt.getId())) {
					continue;
				}
				String statName = "";
				String typeNo = rt.getTypeNo() == null ? "" : rt.getTypeNo();
				Integer statSystem = rt.getStatSystem();
				for (StatSystem ss : statSystems) {
					if (statSystem == ss.getId()) {
						statName = ss.getName();
						break;
					}
				}
				Calendar dateNow = Calendar.getInstance();
				Calendar dateCurr = Calendar.getInstance();

				// 每张报表的延迟时限
				// Integer time_limit = rt.getTime_limit();
				// Integer timeBill =
				// apServiceInterface.queryBillByReport(rt.getId(),
				// unitId, rt.getTypeTime(),
				// rt.getTypeYearTime(), timeDate, quarterDate);
				int month = 0;
				int quarterNow = 1;
				int yearNow = dateNow.get(Calendar.YEAR);
				Date startYear = dateNow.getTime();
				Date endYear = dateNow.getTime();
				for (ReportVersion version : versionList) {
					if (rt.getVersionId().intValue() == version.getId()) {
						startYear = version.getStartDate();
						endYear = version.getEndDate();
						break;
					}
				}
				month = dateNow.get(Calendar.MONTH);
				int monthNow = dateNow.get(Calendar.MONTH) + 1;
				if (monthNow < 4) {
					quarterNow = 1;
				} else if (monthNow > 3 && monthNow < 7) {
					quarterNow = 2;
				} else if (monthNow > 6 && monthNow < 10) {
					quarterNow = 3;
				} else if (monthNow > 9) {
					quarterNow = 4;
				}
				// dateCurr.set(Calendar.DAY_OF_YEAR,
				// dateNow.get(Calendar.DAY_OF_YEAR) - time_limit);
				int day = dateCurr.get(Calendar.DAY_OF_MONTH);
				String typeYear = rt.getTypeYearTime();
				// 下半年报上半年的
				if ("1".equals(rt.getTypeYearTime())) {
					int monthValue = dateNow.get(Calendar.MONTH);
					if (monthValue > 5)
						typeYear = "4";
				}
				List<ReportTypeLimit> limitList = queryReportLimit(rt.getStatSystem(), rt.getId(), rt.getTypeTime(),
						typeYear);
				for (ReportTypeLimit reportLimit : limitList) {
					Integer startDay = reportLimit.getStartDay();
					Integer endDay = reportLimit.getEndDay();
					Integer startMonth = reportLimit.getStartMonth();
					Integer endMonth = reportLimit.getEndMonth();
					// 月报(下月1日+延期)
					if ("0".equals(rt.getTypeTime()) && rt.getTypeTime().equals(reportLimit.getTypeTime())) {
						if (day <= endDay) {
							String dateTime = yearNow + "/" + month;
							if (month < 10) {
								dateTime = yearNow + "/0" + month;
							}
							if (month == 0) {
								dateTime = yearNow - 1 + "/12";
								Calendar now = Calendar.getInstance();
								now.set(Calendar.DAY_OF_MONTH, 1); // 设置日期
								now.set(Calendar.MONTH, month - 1);
								if (now.getTime().compareTo(startYear) == -1 || now.getTime().compareTo(endYear) == 1) {
									break;
								}
							} else {
								if (dateNow.getTime().compareTo(startYear) == -1
										|| dateNow.getTime().compareTo(endYear) == 1) {
									break;
								}
							}
							List<Report> reporteds = queryReportsByBillboar(rt.getId(), rt.getTypeTime(),
									rt.getTypeYearTime(), "", dateTime, "", userid);
							if (reporteds == null) {
								cn.com.generaldata.os.vo.ReportVO report = new cn.com.generaldata.os.vo.ReportVO();
								report.setReportDomainName(dateTime + statName + "：" + typeNo + rt.getTypeName());
								report.setOperatorId(userid);
								report.setReportTypeId(rt.getId());
								report.setReportTimetype(rt.getTypeTime());

								report.setReportUnitIndustry(user2.getUserIndustrys().iterator().next().getIndustry()
										.getId());
								report.setReportYearTime(rt.getTypeYearTime());

								if (month >= 0 && month < 3) {
									report.setReportQuarter("1");
								}
								if (month >= 3 && month < 6) {
									report.setReportQuarter("2");
								}
								if (month >= 6 && month < 9) {
									report.setReportQuarter("3");
								}
								if (month >= 9 && month < 12) {
									report.setReportQuarter("4");
								}

								report.setReportVersion("v1.00.00");
								report.setReportMonth(dateTime);
								result.add(report);
								break;
							}
						}
					}
					// 季报
					else if ("2".equals(rt.getTypeTime()) && rt.getTypeTime().equals(reportLimit.getTypeTime())) {
						int quarter = 0;
						String quarterName = "";
						int year = dateCurr.get(Calendar.YEAR);
						Calendar now = Calendar.getInstance();
						if (month == 3) {
							quarter = 1;
						} else if (month == 6) {
							quarter = 2;
						} else if (month == 9) {
							quarter = 3;
						} else if (month == 0) {
							quarter = 4;
							year--;
							now.set(Calendar.DAY_OF_MONTH, 1); // 设置日期
							now.set(Calendar.MONTH, month - 1);
						}
						if (day <= endDay && quarter != 0) {
							if (quarter == 1) {
								quarterName = "第一季度";
							} else if (quarter == 2) {
								quarterName = "第二季度";
							} else if (quarter == 3) {
								quarterName = "第三季度";
							} else if (quarter == 4) {
								quarterName = "第四季度";
							}
							String dateTime = year + "/" + monthNow;

							if (monthNow < 10) {
								dateTime = year + "/0" + monthNow;
							}
							if (now.getTime().compareTo(startYear) == -1 || now.getTime().compareTo(endYear) == 1) {
								break;
							}
							List<Report> reporteds = queryReportsByBillboar(rt.getId(), rt.getTypeTime(),
									rt.getTypeYearTime(), quarterName, dateTime, "", userid);
							if (reporteds == null) {
								cn.com.generaldata.os.vo.ReportVO report = new cn.com.generaldata.os.vo.ReportVO();
								report.setReportDomainName(year + "年" + quarterName + "季度" + statName + "：" + typeNo
										+ rt.getTypeName());
								report.setOperatorId(userid);
								report.setReportTypeId(rt.getId());
								report.setReportTimetype(rt.getTypeTime());
								report.setReportUnitIndustry(user2.getUserIndustrys().iterator().next().getIndustry()
										.getId());
								report.setReportYearTime(rt.getTypeYearTime());

								report.setReportQuarter(String.valueOf(quarter));

								report.setReportVersion("v1.00.00");
								report.setReportMonth(dateTime);
								result.add(report);
								break;
							}
						}
					}
					// 年报
					else if ("1".equals(rt.getTypeTime()) && rt.getTypeTime().equals(reportLimit.getTypeTime())) {
						int year = dateCurr.get(Calendar.YEAR);
						Calendar now = Calendar.getInstance();
						// 半年报
						if (("1".equals(typeYear) || "4".equals(typeYear))
								&& reportLimit.getTypeYearTime().equals(typeYear)) {
							if (monthNow == startMonth && day <= endDay) {
								if ("1".equals(typeYear)) {
									now.set(Calendar.YEAR, year - 1);
									now.set(Calendar.DAY_OF_MONTH, 1); // 设置日期
									year--;
								}
								if (now.getTime().compareTo(startYear) == -1 || now.getTime().compareTo(endYear) == 1) {
									break;
								}
								String dateTime = year + "/" + monthNow;
								if (monthNow < 10) {
									dateTime = year + "/0" + monthNow;
								}
								List<Report> reporteds = queryReportsByBillboar(rt.getId(), rt.getTypeTime(),
										rt.getTypeYearTime(), "", dateTime, "", userid);
								if (reporteds == null) {
									cn.com.generaldata.os.vo.ReportVO report = new cn.com.generaldata.os.vo.ReportVO();
									if ("1".equals(rt.getTypeYearTime())) {
										report.setReportDomainName(year + statName + "：" + typeNo + rt.getTypeName());
									} else if ("2".equals(rt.getTypeYearTime())) {
										report.setReportDomainName(year + statName + "：" + typeNo + rt.getTypeName());
									} else
										report.setReportDomainName(year + statName + "：" + typeNo + rt.getTypeName());
									report.setOperatorId(userid);
									report.setReportTypeId(rt.getId());
									report.setReportTimetype(rt.getTypeTime());

									report.setReportUnitIndustry(user2.getUserIndustrys().iterator().next()
											.getIndustry().getId());
									report.setReportYearTime(rt.getTypeYearTime());

									if (month >= 0 && month < 3) {
										report.setReportQuarter("1");
									}
									if (month >= 3 && month < 6) {
										report.setReportQuarter("2");
									}
									if (month >= 6 && month < 9) {
										report.setReportQuarter("3");
									}
									if (month >= 9 && month < 12) {
										report.setReportQuarter("4");
									}

									report.setReportVersion("v1.00.00");
									report.setReportMonth(dateTime);
									result.add(report);
									break;
								}
							}
						}
						// 全年报
						else if ("2".equals(rt.getTypeYearTime()) && reportLimit.getTypeYearTime().equals(typeYear)) {
							if (monthNow >= startMonth && monthNow <= endMonth && day <= endDay) {
								now.set(Calendar.YEAR, year - 1);
								now.set(Calendar.DAY_OF_MONTH, 1); // 设置日期
								year--;
								if (now.getTime().compareTo(startYear) == -1 || now.getTime().compareTo(endYear) == 1) {
									break;
								}
								String dateTime = year + "/" + monthNow;
								if (monthNow < 10) {
									dateTime = year + "/0" + monthNow;
								}
								List<Report> reporteds = queryReportsByBillboar(rt.getId(), rt.getTypeTime(),
										rt.getTypeYearTime(), "", dateTime, "", userid);
								if (reporteds == null) {
									cn.com.generaldata.os.vo.ReportVO report = new cn.com.generaldata.os.vo.ReportVO();
									if ("1".equals(rt.getTypeYearTime())) {
										report.setReportDomainName(year + statName + "：" + typeNo + rt.getTypeName());
									} else if ("2".equals(rt.getTypeYearTime())) {
										report.setReportDomainName(year + statName + "：" + typeNo + rt.getTypeName());
									} else
										report.setReportDomainName(year + statName + "：" + typeNo + rt.getTypeName());
									report.setOperatorId(userid);
									report.setReportTypeId(rt.getId());
									report.setReportTimetype(rt.getTypeTime());

									report.setReportUnitIndustry(user2.getUserIndustrys().iterator().next()
											.getIndustry().getId());
									report.setReportYearTime(rt.getTypeYearTime());

									if (month >= 0 && month < 3) {
										report.setReportQuarter("1");
									}
									if (month >= 3 && month < 6) {
										report.setReportQuarter("2");
									}
									if (month >= 6 && month < 9) {
										report.setReportQuarter("3");
									}
									if (month >= 9 && month < 12) {
										report.setReportQuarter("4");
									}

									report.setReportVersion("v1.00.00");
									report.setReportMonth(dateTime);
									result.add(report);
									break;
								}
							}
						}

					}

				}
			}
		}

		return result;
	}

	public Integer queryBillByReport(String reportTypeId, String unitId, String timeType, String yearType,
			String timeDate, String quarter) {

		HashMap param = new HashMap();
		String hql = "from BillboardIndustryReports br where reportTypeCode=:reportTypeCode and reportTypeTime=:reportTypeTime and billboardTime=:billboardTime and  exists (select bi.id from BillboardIndustry as bi where br.billboardIndustryId=bi.id and bi.users like :unitId)";
		// 年报
		if ("1".equals(timeType)) {
			hql += " and reportYearTime=:reportYearTime";
			param.put("reportYearTime", yearType);
		}
		// 季报
		else if ("2".equals(timeType)) {
			hql += " and billboardTimeQuarter=:billboardTimeQuarter";
			param.put("billboardTimeQuarter", quarter);
		}
		param.put("reportTypeCode", reportTypeId);
		param.put("reportTypeTime", timeType);
		param.put("billboardTime", timeDate);
		param.put("unitId", "%" + unitId + "%");
		Result list = billboardIndustryReportsDAO.hqlParam(hql, param, null);
		if (list != null && list.getOperationResult().size() > 0) {
			List<BillboardIndustryReports> operationResult = (List<BillboardIndustryReports>) list.getOperationResult();
			return operationResult.get(0).getTimeLimit();
		}
		return null;
	}

	/**
	 * 所有相关报表
	 * 
	 * @param unitId
	 * @param timeType
	 */
	public List<cn.com.generaldata.os.vo.ReportVO> reportAllQuery(String userId, String systemType,
			Date startingReportDate, Date endingReportDate, String proxyId) {

		String hql = "select rt.id,rt.stat_system,rt.version_id,rt.type_name,rt.type_no,rt.type_year_time,rt.type_time from tbl_report_type rt where 1=1";
		Calendar date = Calendar.getInstance();
		// 只查询能填报的
		// hql += " and usage_mode<>" +
		// Constants.ReportTypeUsageMode.EXPORT.getValue();
		Map<String, Object> param = Maps.newHashMap();
		if (systemType != null && !"".equals(systemType)) {
			hql += " and rt.stat_system=@systemType";
			param.put("systemType", systemType);
		}
		if (startingReportDate != null) {
			hql += " and EXISTS(select rv.id from tbl_report_version rv where rv.stat_system=rt.stat_system and rv.id=rt.version_id and rv.start_date <=@startingReportDate and rv.end_date>=@endingReportDate)";
			param.put("startingReportDate", startingReportDate);
			param.put("endingReportDate", endingReportDate);
		}
		hql += " order by rt.sort_no, rt.sub_sort_no";
		// 查询所有报表
		List<ReportTypeNz> rgrs = sqlTemplate.query(hql, param, indicatorSystemDao.getEntity(ReportTypeNz.class));
		// List<ReportVersion> versionList =
		// versionDAO.find(ReportVersion.class, null, null);

		List<cn.com.generaldata.os.vo.ReportVO> result = new ArrayList<cn.com.generaldata.os.vo.ReportVO>();
		//外网只看代填人能填写什么
		User user = userDAO.get(User.class, proxyId);

		Filter filter = new Filter();
		filter.addRule(new FilterRule(FilterConstant.EQUAL, "userUnit.id", user.getUserUnit().getId()));
		// 该单位的所有用户
		List<User> users = userDAO.find(User.class, filter, null);
		if (users != null && users.size() > 0) {
			// 该单位所有报表分组ID
			List<String> groupIds = new ArrayList<String>();
			List<String> uids = new ArrayList<String>();
			for (User user2 : users) {
				uids.add(user2.getId());
			}
			if (uids.size() == 0) {
				uids.add("");
			}
			Filter filterIndustry = new Filter();
			filterIndustry.addRule(new FilterRule(FilterConstant.COLLECTION, "user.id", uids.toArray()));
			List<UserIndustry> userIndustrys = userIndustryDAO.find(UserIndustry.class, filterIndustry, null);
			if (userIndustrys != null && userIndustrys.size() > 0) {
				for (int i = 0; i < userIndustrys.size(); i++) {
					groupIds.add(userIndustrys.get(i).getIndustry().getId());
				}
			}
			if (groupIds.size() == 0) {
				groupIds.add("");
			}
			// 分组对应的报表
			List<String> groupRel = queryReportGroupRel(groupIds);
			// 该单位需要报的报表
			List<ReportTypeNz> list = new ArrayList<ReportTypeNz>();

			// 判断用户身份(企业用户、涉海部门要过滤)
			List<String> queryReportTypesUnit = queryReportTypesUnit(user.getUserUnit().getId());

			if (queryReportTypesUnit != null && queryReportTypesUnit.size() > 0) {
				groupRel = queryReportTypesUnit;
			}
			
			groupRel.addAll(queryReportNation(userId));	//企业用户根据产业类型过滤需要填报的报表模板
			
			List<String> listIds = new ArrayList<String>();
			if (groupRel.size() > 0) {
				for (ReportTypeNz rt : rgrs) {
					// 分组报表在查询范围内的
					if (groupRel.contains(rt.getId())) {
						list.add(rt);
						listIds.add(rt.getId());
					}
				}

			}			

			// 该制度这段时间所有属于这个单位的报表
			if (list != null && list.size() > 0) {
				List<cn.com.generaldata.os.vo.ReportVO> reportList = new ArrayList<cn.com.generaldata.os.vo.ReportVO>();
				Calendar dateStart = Calendar.getInstance();
				Calendar dateEnd = Calendar.getInstance();
				dateEnd.setTime(endingReportDate);
				dateStart.setTime(startingReportDate);
				int dayStart = dateStart.get(Calendar.DATE);
				int dayEnd = dateEnd.get(Calendar.DATE);
				int month = dateEnd.get(Calendar.MONTH);
				int year = dateEnd.get(Calendar.YEAR);

				//				Integer unitLevel = userService.getUnitLevel(user.getUserUnit().getId());
				//查询近两年该单位填报的所有相关报表
				String[] years = new String[] { String.valueOf(year), String.valueOf(year - 1) };
				String sql = "select r.* from tbl_report r where r.report_type_id in(@reportType) and exists(select u.id from tbl_user u where u.id=r.report_user_id and u.user_unit=@unitId) and report_year in(@year)";
				HashMap map = new HashMap();
				map.put("reportType", listIds.toArray());
				map.put("unitId", user.getUserUnit().getId());
				map.put("year", years);
				//所有填报过的报表
				List<ReportNz> reports = sqlTemplate.query(sql, map, indicatorSystemDao.getEntity(ReportNz.class));
				//查询所有报表时限
				List<ReportTypeLimit> limitList = queryReportLimit(Integer.valueOf(systemType), null, null, null);
				for (ReportTypeNz rt : list) {
					//					if (queryReportTypesUnit.size() > 0 && !queryReportTypesUnit.contains(rt.getId())) {
					//						continue;
					//					}
					//					String sql = "select r.* from tbl_report r where r.report_type_id=@reportType and r.unit_id =@unitId and report_year=@year";
					cn.com.generaldata.os.vo.ReportVO report = new cn.com.generaldata.os.vo.ReportVO();
					report.setReportTypeId(rt.getId());
					//					report.setUnitId(user.getUserUnit().getId());
					report.setUserId(userId);
					report.setReportUnitIndustry("");
					report.setReportTimetype(rt.getTypeTime());
					report.setReportYearTime(rt.getTypeYearTime());
					for (ReportTypeLimit reportLimit : limitList) {
						Integer startDay = reportLimit.getStartDay();
						Integer endDay = reportLimit.getEndDay();
						Integer startMonth = reportLimit.getStartMonth();
						Integer endMonth = reportLimit.getEndMonth();
						//所查模板的类型与时限的类型一致
						if (rt.getStatSystem().equals(reportLimit.getStatSystem())
								&& rt.getTypeTime().equals(reportLimit.getTypeTime())) {
							//								&& (unitLevel == reportLimit.getLevel() || reportLimit.getLevel() == null)) {
							//具体模板ID不符
							if (StringUtils.isNotBlank(reportLimit.getTypeId())
									&& !rt.getId().equals(reportLimit.getTypeId()))
								continue;
							//不能提前上报
							if (dayEnd < startDay)
								break;
							report = validateReport(rt, month, year, report, endDay, startMonth, endMonth, reports);
							if (report != null)
								result.add(report);
							break;
						}
					}
				}
			}
		}
		return result;
	}

	/**
	 * 验证报表是否填报、迟报、修改等
	 * @param rt
	 * @param month
	 * @param year
	 * @param report
	 * @param endDay
	 * @param startMonth
	 * @param endMonth
	 * @param reports
	 * @return
	 */
	public ReportVO validateReport(ReportTypeNz rt, int month, int year, ReportVO report, Integer endDay,
			Integer startMonth, Integer endMonth, List<ReportNz> reports) {
		String monthValue = "";
		Calendar dateOK = Calendar.getInstance();
		Calendar dateNow = Calendar.getInstance();
		Boolean delay = false;
		int quarter = 0;

		//月报
		if (String.valueOf(Constants.REPORT_TIME_MONTH).equals(rt.getTypeTime())) {
			//去年12月
			if (month == 0) {
				month = 12;
				year--;
			}
			if (month < 10)
				monthValue = year + "/0" + (month);
			else
				monthValue = year + "/" + (month);
			int i = 0;
			for (ReportNz rz : reports) {
				if (rz.getReportTypeId().equals(rt.getId()) && rz.getMonth().equals(Integer.valueOf(month))
						&& rz.getReportYear().equals(String.valueOf(year))) {
					report.setId(rz.getId());
					//被驳回的或者保存或者提交且是有限期内的
					if (Integer.valueOf(ReportConstant.FLAG_PROVINCE_REJECTED) == rz.getReportCheckStatus()
							|| (Integer.valueOf(ReportConstant.FLAG_UNCOMMITTED) == rz.getReportCheckStatus()))
						report.setStatus(Integer.valueOf(Constants.UPDATE));
					else
						report.setStatus(Integer.valueOf(Constants.DETAIL));
					report.setReportCheckStatus(rz.getReportCheckStatus().shortValue());
					break;
				}
				i++;
			}
			report.setReportYear(String.valueOf(year));
			report.setReportQuarter("");
			//可填报期限
			dateOK.set(Calendar.YEAR, Integer.valueOf(year));
			dateOK.set(Calendar.MONTH, Integer.valueOf(month) + 1);
			dateOK.set(Calendar.DATE, endDay);
			//若当天大于可填报期限就是迟报
			if (dateNow.after(dateOK)) {
				delay = true;
			}
			//未填报过
			if (i == reports.size()) {
				report.setId("");
				//有迟报标记
				if (delay)
					report.setStatus(Integer.valueOf(Constants.DELAY));
				else
					report.setStatus(Integer.valueOf(Constants.SUBMIT));
			}
			report.setReportDomainName(monthValue + ": " + rt.getTypeNo() + "_" + rt.getTypeName());
		}
		// 季报
		else if (String.valueOf(Constants.REPORT_TIME_QUARTER).equals(rt.getTypeTime())) {
			String quarterName = "";
			if (month == 3) {
				quarter = 1;
				quarterName = "第一季度";
				dateOK.set(Calendar.YEAR, Integer.valueOf(year));
				dateOK.set(Calendar.MONTH, 3);
			} else if (month == 6) {
				quarter = 2;
				quarterName = "第二季度";
				dateOK.set(Calendar.YEAR, Integer.valueOf(year));
				dateOK.set(Calendar.MONTH, 6);
			} else if (month == 9) {
				quarter = 3;
				quarterName = "第三季度";
				dateOK.set(Calendar.YEAR, Integer.valueOf(year));
				dateOK.set(Calendar.MONTH, 9);
			} else if (month == 0) {
				quarter = 4;
				quarterName = "第四季度";
				year--;
				dateOK.set(Calendar.YEAR, Integer.valueOf(year) + 1);
				dateOK.set(Calendar.MONTH, 0);
			}
			//这个月不用报季报
			else {
				return null;
			}
			if (month < 9)
				monthValue = year + "/0" + (month + 1);
			else
				monthValue = year + "/" + (month + 1);
			int i = 0;
			for (ReportNz rz : reports) {
				if (rz.getReportTypeId().equals(rt.getId()) && rz.getQuarter().equals(Integer.valueOf(quarter))
						&& rz.getReportYear().equals(String.valueOf(year))) {
					report.setId(rz.getId());
					//被驳回的或者保存或者提交且是有限期内的
					if (Integer.valueOf(ReportConstant.FLAG_PROVINCE_REJECTED) == rz.getReportCheckStatus()
							|| (Integer.valueOf(ReportConstant.FLAG_UNCOMMITTED) == rz.getReportCheckStatus()))
						report.setStatus(Integer.valueOf(Constants.UPDATE));
					else
						report.setStatus(Integer.valueOf(Constants.DETAIL));
					report.setReportCheckStatus(rz.getReportCheckStatus().shortValue());
					break;
				}
				i++;
			}
			//可填报期限
			dateOK.set(Calendar.DATE, endDay);
			//若当天大于可填报期限就是迟报
			if (dateNow.after(dateOK)) {
				delay = true;
			}
			//未填报过
			if (i == reports.size()) {
				report.setId("");
				//有迟报标记
				if (delay)
					report.setStatus(Integer.valueOf(Constants.DELAY));
				else
					report.setStatus(Integer.valueOf(Constants.SUBMIT));
			}
			report.setReportQuarter(String.valueOf(quarter));
			report.setReportDomainName(year + "年" + quarterName + ": " + rt.getTypeNo() + "_" + rt.getTypeName());
		}
		// 年报
		else if (String.valueOf(Constants.REPORT_TIME_YEAR).equals(rt.getTypeTime())) {
			//不能提前上报
			if (month + 1 < startMonth)
				return null;
			String yearTime = String.valueOf(Constants.REPORT_FULL_YEAR);
			// 当年上半年报不用-1
			if ("1".equals(rt.getTypeYearTime()) && month > 5) {
				yearTime = String.valueOf(Constants.REPORT_HALF_YEAR);
				dateOK.set(Calendar.YEAR, Integer.valueOf(year));
			} else {
				year--;
				dateOK.set(Calendar.YEAR, Integer.valueOf(year) + 1);
			}
			int i = 0;
			for (ReportNz rz : reports) {
				if (rz.getReportTypeId().equals(rt.getId()) && rz.getReportYearTime().equals(yearTime)
						&& rz.getReportYear().equals(String.valueOf(year))) {
					report.setId(rz.getId());
					//被驳回的或者保存或者提交且是有限期内的
					if (Integer.valueOf(ReportConstant.FLAG_PROVINCE_REJECTED) == rz.getReportCheckStatus()
							|| (Integer.valueOf(ReportConstant.FLAG_UNCOMMITTED) == rz.getReportCheckStatus()))
						report.setStatus(Integer.valueOf(Constants.UPDATE));
					else
						report.setStatus(Integer.valueOf(Constants.DETAIL));
					report.setReportCheckStatus(rz.getReportCheckStatus().shortValue());
					break;
				}
				i++;
			}
			if (month < 9)
				monthValue = year + "/0" + (month + 1);
			else
				monthValue = year + "/" + (month + 1);
			dateOK.set(Calendar.MONTH, endMonth - 1);
			dateOK.set(Calendar.DATE, endDay);
			//若当天大于可填报期限就是迟报
			if (dateNow.after(dateOK)) {
				delay = true;
			}
			//未填报过
			if (i == reports.size()) {
				report.setId("");
				//有迟报标记
				if (delay)
					report.setStatus(Integer.valueOf(Constants.DELAY));
				else
					report.setStatus(Integer.valueOf(Constants.SUBMIT));
			}
			report.setReportYearTime(yearTime);
			report.setReportQuarter("");
			report.setReportDomainName(year + "年: " + rt.getTypeNo() + "_" + rt.getTypeName());
		}

		report.setReportName(rt.getTypeName());
		report.setReportMonth(monthValue);
		return report;

	}

	/**
	 * 根据分组查询报表
	 */
	public List<String> queryReportGroupRel(List<String> groupId) {
		SqlExpressionGroup exp1 = Cnd.exps("industryId", "in", groupId.toArray());
		Cnd and = Cnd.where(exp1);
		List<DustryReportNz> list = indicatorSystemDao.query(DustryReportNz.class, and);
		List<String> reportIds = new ArrayList<String>();
		for (DustryReportNz rgr : list)
			reportIds.add(rgr.getReportTypeId());
		return reportIds;
	}

	/**
	 * 报表时间值对象.
	 */
	class ReportTimeVO {
		Integer timeType;
		Integer year;
		Integer yearTime;
		Integer quarter;
		Integer month;

		public ReportTimeVO(Integer timeType, Integer year, Integer yearTime, Integer quarter, Integer month) {
			this.timeType = timeType;
			this.year = year;
			this.yearTime = yearTime;
			this.quarter = quarter;
			this.month = month;
		}

	}

	/**
	 * 根据用户身份匹配产业类型，过滤对应的报表
	 */
	public List<String> queryReportNation(String userId) {

		List<String> reportIds = new ArrayList<String>();
		String sql =  " select ut.report_type_id from t_unit_nation n " 
				+ " left join tbl_unittype_report ut on (n.hy_code = ut.type_code or n.unit_type = ut.unit_type) "
				+ " left join tbl_report_type type on type.id = ut.report_type_id "
				+ " left join t_stat_system s on s.id = type.stat_system left join tbl_unit un on un.id = n.unit_id "
				+ " left join tbl_user u on u.user_unit = un.id  where u.id = @userId ";
		
		Map params = new HashMap();
		params.put("userId", userId);
		
		List<Record> list = sqlTemplate.queryRecords(sql, null, params);

		for (Record re :  list){
			reportIds.add(re.getString("report_type_id"));
		}
		return reportIds;
	}
}
